Author: akhaldi
Date: Wed Sep 7 22:32:56 2016
New Revision: 72611
URL:
http://svn.reactos.org/svn/reactos?rev=72611&view=rev
Log:
[KERNEL32_WINETEST] Sync with Wine Staging 1.9.18.
Modified:
trunk/rostests/winetests/kernel32/console.c
trunk/rostests/winetests/kernel32/fiber.c
trunk/rostests/winetests/kernel32/file.c
trunk/rostests/winetests/kernel32/loader.c
trunk/rostests/winetests/kernel32/locale.c
trunk/rostests/winetests/kernel32/path.c
trunk/rostests/winetests/kernel32/thread.c
trunk/rostests/winetests/kernel32/virtual.c
Modified: trunk/rostests/winetests/kernel32/console.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/consol…
==============================================================================
--- trunk/rostests/winetests/kernel32/console.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/console.c [iso-8859-1] Wed Sep 7 22:32:56 2016
@@ -906,6 +906,58 @@
/* restore codepage */
SetConsoleOutputCP(oldcp);
+}
+
+static void CALLBACK signaled_function(void *p, BOOLEAN timeout)
+{
+ HANDLE event = p;
+ SetEvent(event);
+ ok(!timeout, "wait shouldn't have timed out\n");
+}
+
+static void testWaitForConsoleInput(HANDLE input_handle)
+{
+ HANDLE wait_handle;
+ HANDLE complete_event;
+ INPUT_RECORD record;
+ DWORD events_written;
+ DWORD wait_ret;
+ BOOL ret;
+
+ complete_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+
+ /* Test success case */
+ ret = RegisterWaitForSingleObject(&wait_handle, input_handle, signaled_function,
complete_event, INFINITE, WT_EXECUTEONLYONCE);
+ ok(ret == TRUE, "Expected RegisterWaitForSingleObject to return TRUE, got
%d\n", ret);
+ /* give worker thread a chance to start up */
+ Sleep(100);
+ record.EventType = KEY_EVENT;
+ record.Event.KeyEvent.bKeyDown = 1;
+ record.Event.KeyEvent.wRepeatCount = 1;
+ record.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
+ record.Event.KeyEvent.wVirtualScanCode = VK_RETURN;
+ record.Event.KeyEvent.uChar.UnicodeChar = '\r';
+ record.Event.KeyEvent.dwControlKeyState = 0;
+ ret = WriteConsoleInputW(input_handle, &record, 1, &events_written);
+ ok(ret == TRUE, "Expected WriteConsoleInputW to return TRUE, got %d\n",
ret);
+ wait_ret = WaitForSingleObject(complete_event, INFINITE);
+ ok(wait_ret == WAIT_OBJECT_0, "Expected the handle to be signaled\n");
+ ret = UnregisterWait(wait_handle);
+ /* If the callback is still running, this fails with ERROR_IO_PENDING, but
+ that's ok and expected. */
+ ok(ret != 0 || GetLastError() == ERROR_IO_PENDING,
+ "UnregisterWait failed with error %d\n", GetLastError());
+
+ /* Test timeout case */
+ FlushConsoleInputBuffer(input_handle);
+ ret = RegisterWaitForSingleObject(&wait_handle, input_handle, signaled_function,
complete_event, INFINITE, WT_EXECUTEONLYONCE);
+ wait_ret = WaitForSingleObject(complete_event, 100);
+ ok(wait_ret == WAIT_TIMEOUT, "Expected the wait to time out\n");
+ ret = UnregisterWait(wait_handle);
+ ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
+
+ /* Clean up */
+ ok(CloseHandle(complete_event), "Failed to close event handle, last error
%d\n", GetLastError());
}
static void test_GetSetConsoleInputExeName(void)
@@ -2938,6 +2990,55 @@
todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected
87\n", GetLastError());
}
+static void test_GetConsoleScreenBufferInfoEx(HANDLE std_output)
+{
+ HANDLE hmod;
+ BOOL (WINAPI *pGetConsoleScreenBufferInfoEx)(HANDLE, CONSOLE_SCREEN_BUFFER_INFOEX
*);
+ CONSOLE_SCREEN_BUFFER_INFOEX csbix;
+ BOOL ret;
+ HANDLE std_input = GetStdHandle(STD_INPUT_HANDLE);
+
+ hmod = GetModuleHandleA("kernel32.dll");
+ pGetConsoleScreenBufferInfoEx = (void *)GetProcAddress(hmod,
"GetConsoleScreenBufferInfoEx");
+ if (!pGetConsoleScreenBufferInfoEx)
+ {
+ win_skip("GetConsoleScreenBufferInfoEx is not available\n");
+ return;
+ }
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleScreenBufferInfoEx(NULL, &csbix);
+ ok(!ret, "got %d, expected zero\n", ret);
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n",
GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleScreenBufferInfoEx(std_input, &csbix);
+ ok(!ret, "got %d, expected zero\n", ret);
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n",
GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleScreenBufferInfoEx(std_output, &csbix);
+ ok(!ret, "got %d, expected zero\n", ret);
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 87\n",
GetLastError());
+
+ csbix.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleScreenBufferInfoEx(NULL, &csbix);
+ ok(!ret, "got %d, expected zero\n", ret);
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n",
GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleScreenBufferInfoEx(std_input, &csbix);
+ ok(!ret, "got %d, expected zero\n", ret);
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n",
GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleScreenBufferInfoEx(std_output, &csbix);
+ ok(ret, "got %d, expected non-zero\n", ret);
+ ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n",
GetLastError());
+}
+
START_TEST(console)
{
static const char font_name[] = "Lucida Console";
@@ -3044,6 +3145,8 @@
testScroll(hConOut, sbi.dwSize);
/* will test sb creation / modification / codepage handling */
testScreenBuffer(hConOut);
+ /* Test waiting for a console handle */
+ testWaitForConsoleInput(hConIn);
/* clear duplicated console font table */
CloseHandle(hConIn);
@@ -3086,4 +3189,5 @@
test_GetLargestConsoleWindowSize(hConOut);
test_GetConsoleFontInfo(hConOut);
test_SetConsoleFont(hConOut);
-}
+ test_GetConsoleScreenBufferInfoEx(hConOut);
+}
Modified: trunk/rostests/winetests/kernel32/fiber.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/fiber.…
==============================================================================
--- trunk/rostests/winetests/kernel32/fiber.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/fiber.c [iso-8859-1] Wed Sep 7 22:32:56 2016
@@ -155,28 +155,20 @@
ok(fiberCount == 1, "Wrong fiber count: %d\n", fiberCount);
pDeleteFiber(fibers[1]);
- if (!pCreateFiberEx)
- {
- win_skip( "CreateFiberEx not present\n" );
- return;
- }
-
- fibers[1] = pCreateFiberEx(0,0,0,FiberMainProc,&testparam);
- ok(fibers[1] != NULL, "CreateFiberEx failed with error %u\n",
GetLastError());
-
- pSwitchToFiber(fibers[1]);
- ok(fiberCount == 2, "Wrong fiber count: %d\n", fiberCount);
- pDeleteFiber(fibers[1]);
-
- if (!pIsThreadAFiber)
- {
- win_skip( "IsThreadAFiber not present\n" );
- return;
- }
-
- ok(pIsThreadAFiber(), "IsThreadAFiber reported FALSE\n");
+ if (pCreateFiberEx)
+ {
+ fibers[1] = pCreateFiberEx(0,0,0,FiberMainProc,&testparam);
+ ok(fibers[1] != NULL, "CreateFiberEx failed with error %u\n",
GetLastError());
+
+ pSwitchToFiber(fibers[1]);
+ ok(fiberCount == 2, "Wrong fiber count: %d\n", fiberCount);
+ pDeleteFiber(fibers[1]);
+ }
+ else win_skip( "CreateFiberEx not present\n" );
+
+ if (pIsThreadAFiber) ok(pIsThreadAFiber(), "IsThreadAFiber reported
FALSE\n");
test_ConvertFiberToThread();
- ok(!pIsThreadAFiber(), "IsThreadAFiber reported TRUE\n");
+ if (pIsThreadAFiber) ok(!pIsThreadAFiber(), "IsThreadAFiber reported
TRUE\n");
}
static void test_FiberLocalStorage(void)
Modified: trunk/rostests/winetests/kernel32/file.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/file.c…
==============================================================================
--- trunk/rostests/winetests/kernel32/file.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/file.c [iso-8859-1] Wed Sep 7 22:32:56 2016
@@ -4449,17 +4449,10 @@
else
{
/* FIXME: Remove once Wine is fixed */
- if ((td[j].access & (GENERIC_READ | GENERIC_WRITE)) ||
- (!(td[i].access & (GENERIC_WRITE | FILE_WRITE_DATA)) &&
(td[j].access & FILE_WRITE_DATA)) ||
- (!(td[i].access & (GENERIC_READ | FILE_READ_DATA)) &&
(td[j].access & FILE_READ_DATA)) ||
- (!(td[i].access & (GENERIC_WRITE)) && (td[j].access &
FILE_APPEND_DATA)))
- {
-todo_wine
- ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n",
td[i].access, td[j].access);
-todo_wine
- ok(GetLastError() == ERROR_ACCESS_DENIED, "expected
ERROR_ACCESS_DENIED, got %d\n", GetLastError());
- }
- else
+ todo_wine_if((td[j].access & (GENERIC_READ | GENERIC_WRITE) ||
+ (!(td[i].access & (GENERIC_WRITE | FILE_WRITE_DATA))
&& (td[j].access & FILE_WRITE_DATA)) ||
+ (!(td[i].access & (GENERIC_READ | FILE_READ_DATA))
&& (td[j].access & FILE_READ_DATA)) ||
+ (!(td[i].access & (GENERIC_WRITE)) &&
(td[j].access & FILE_APPEND_DATA))))
{
ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n",
td[i].access, td[j].access);
ok(GetLastError() == ERROR_ACCESS_DENIED, "expected
ERROR_ACCESS_DENIED, got %d\n", GetLastError());
Modified: trunk/rostests/winetests/kernel32/loader.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/loader…
==============================================================================
--- trunk/rostests/winetests/kernel32/loader.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/loader.c [iso-8859-1] Wed Sep 7 22:32:56 2016
@@ -70,6 +70,10 @@
PDELAYLOAD_FAILURE_DLL_CALLBACK, PVOID,
PIMAGE_THUNK_DATA ThunkAddress,ULONG);
static PVOID (WINAPI *pRtlImageDirectoryEntryToData)(HMODULE,BOOL,WORD,ULONG *);
+static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
+static BOOL (WINAPI *pFlsSetValue)(DWORD, PVOID);
+static PVOID (WINAPI *pFlsGetValue)(DWORD);
+static BOOL (WINAPI *pFlsFree)(DWORD);
static PVOID RVAToAddr(DWORD_PTR rva, HMODULE module)
{
@@ -143,9 +147,9 @@
static IMAGE_SECTION_HEADER section =
{
".rodata", /* Name */
- { 0x10 }, /* Misc */
+ { 0 }, /* Misc */
0, /* VirtualAddress */
- 0x0a, /* SizeOfRawData */
+ 0, /* SizeOfRawData */
0, /* PointerToRawData */
0, /* PointerToRelocations */
0, /* PointerToLinenumbers */
@@ -196,6 +200,8 @@
assert(nt_header->FileHeader.NumberOfSections <= 1);
if (nt_header->FileHeader.NumberOfSections)
{
+ section.SizeOfRawData = 10;
+
if (nt_header->OptionalHeader.SectionAlignment >= page_size)
{
section.PointerToRawData = dos_size;
@@ -262,9 +268,13 @@
ok( image.CommittedStackSize == nt_header->OptionalHeader.SizeOfStackCommit ||
broken(truncated),
"%u: CommittedStackSize wrong %lx / %lx\n", id,
image.CommittedStackSize, (SIZE_T)nt_header->OptionalHeader.SizeOfStackCommit
);
- ok( image.SubSystemType == nt_header->OptionalHeader.Subsystem ||
broken(truncated),
- "%u: SubSystemType wrong %08x / %08x\n", id,
- image.SubSystemType, nt_header->OptionalHeader.Subsystem );
+ if (truncated)
+ ok( !image.SubSystemType || broken(truncated),
+ "%u: SubSystemType wrong %08x / 00000000\n", id,
image.SubSystemType );
+ else
+ ok( image.SubSystemType == nt_header->OptionalHeader.Subsystem,
+ "%u: SubSystemType wrong %08x / %08x\n", id,
+ image.SubSystemType, nt_header->OptionalHeader.Subsystem );
ok( image.SubsystemVersionLow == nt_header->OptionalHeader.MinorSubsystemVersion,
"%u: SubsystemVersionLow wrong %04x / %04x\n", id,
image.SubsystemVersionLow, nt_header->OptionalHeader.MinorSubsystemVersion );
@@ -1470,6 +1480,7 @@
static DWORD attached_thread_count;
HANDLE stop_event, event, mutex, semaphore, loader_lock_event, peb_lock_event,
heap_lock_event, ack_event;
static int test_dll_phase, inside_loader_lock, inside_peb_lock, inside_heap_lock;
+static LONG fls_callback_count;
static DWORD WINAPI mutex_thread_proc(void *param)
{
@@ -1552,9 +1563,18 @@
return 195;
}
+static VOID WINAPI fls_callback(PVOID lpFlsData)
+{
+ ok(lpFlsData == (void*) 0x31415, "lpFlsData is %p, expected %p\n",
lpFlsData, (void*) 0x31415);
+ InterlockedIncrement(&fls_callback_count);
+}
+
static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param)
{
static LONG noop_thread_started;
+ static DWORD fls_index = FLS_OUT_OF_INDEXES;
+ static int fls_count = 0;
+ static int thread_detach_count = 0;
DWORD ret;
ok(!inside_loader_lock, "inside_loader_lock should not be set\n");
@@ -1567,6 +1587,23 @@
ret = pRtlDllShutdownInProgress();
ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
+
+ /* Set up the FLS slot, if FLS is available */
+ if (pFlsGetValue)
+ {
+ void* value;
+ BOOL bret;
+ ret = pFlsAlloc(&fls_callback);
+ ok(ret != FLS_OUT_OF_INDEXES, "FlsAlloc returned %d\n", ret);
+ fls_index = ret;
+ SetLastError(0xdeadbeef);
+ value = pFlsGetValue(fls_index);
+ ok(!value, "FlsGetValue returned %p, expected NULL\n", value);
+ ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error
%u\n", GetLastError());
+ bret = pFlsSetValue(fls_index, (void*) 0x31415);
+ ok(bret, "FlsSetValue failed\n");
+ fls_count++;
+ }
break;
case DLL_PROCESS_DETACH:
@@ -1619,6 +1656,43 @@
/* FIXME: remove once Wine is fixed */
todo_wine_if (!(expected_code == STILL_ACTIVE || expected_code == 196))
ok(!ret || broken(ret) /* before Vista */, "RtlDllShutdownInProgress
returned %d\n", ret);
+ }
+
+ /* In the case that the process is terminating, FLS slots should still be
accessible, but
+ * the callback should be already run for this thread and the contents already
NULL.
+ * Note that this is broken for Win2k3, which runs the callbacks *after* the DLL
entry
+ * point has already run.
+ */
+ if (param && pFlsGetValue)
+ {
+ void* value;
+ SetLastError(0xdeadbeef);
+ value = pFlsGetValue(fls_index);
+ todo_wine
+ {
+ ok(broken(value == (void*) 0x31415) || /* Win2k3 */
+ value == NULL, "FlsGetValue returned %p, expected NULL\n",
value);
+ }
+ ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error
%u\n", GetLastError());
+ todo_wine
+ {
+ ok(broken(fls_callback_count == thread_detach_count) || /* Win2k3 */
+ fls_callback_count == thread_detach_count + 1,
+ "wrong FLS callback count %d, expected %d\n",
fls_callback_count, thread_detach_count + 1);
+ }
+ }
+ if (pFlsFree)
+ {
+ BOOL ret;
+ /* Call FlsFree now and run the remaining callbacks from uncleanly terminated
threads */
+ ret = pFlsFree(fls_index);
+ ok(ret, "FlsFree failed with error %u\n", GetLastError());
+ fls_index = FLS_OUT_OF_INDEXES;
+ todo_wine
+ {
+ ok(fls_callback_count == fls_count,
+ "wrong FLS callback count %d, expected %d\n",
fls_callback_count, fls_count);
+ }
}
ok(attached_thread_count >= 2, "attached thread count should be >=
2\n");
@@ -1791,9 +1865,26 @@
0, TRUE, DUPLICATE_SAME_ACCESS);
attached_thread_count++;
}
+
+ /* Make sure the FLS slot is empty, if FLS is available */
+ if (pFlsGetValue)
+ {
+ void* value;
+ BOOL ret;
+ SetLastError(0xdeadbeef);
+ value = pFlsGetValue(fls_index);
+ ok(!value, "FlsGetValue returned %p, expected NULL\n", value);
+ todo_wine
+ ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error
%u\n", GetLastError());
+ ret = pFlsSetValue(fls_index, (void*) 0x31415);
+ ok(ret, "FlsSetValue failed\n");
+ fls_count++;
+ }
+
break;
case DLL_THREAD_DETACH:
trace("dll: %p, DLL_THREAD_DETACH, %p\n", hinst, param);
+ thread_detach_count++;
ret = pRtlDllShutdownInProgress();
/* win7 doesn't allow creating a thread during process shutdown but
@@ -1805,6 +1896,23 @@
else
ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
+ /* FLS data should already be destroyed, if FLS is available.
+ * Note that this is broken for Win2k3, which runs the callbacks *after* the DLL
entry
+ * point has already run.
+ */
+ if (pFlsGetValue && fls_index != FLS_OUT_OF_INDEXES)
+ {
+ void* value;
+ SetLastError(0xdeadbeef);
+ value = pFlsGetValue(fls_index);
+ todo_wine
+ {
+ ok(broken(value == (void*) 0x31415) || /* Win2k3 */
+ !value, "FlsGetValue returned %p, expected NULL\n", value);
+ }
+ ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error
%u\n", GetLastError());
+ }
+
break;
default:
trace("dll: %p, %d, %p\n", hinst, reason, param);
@@ -2126,7 +2234,6 @@
} section_data = { 0xb8, dll_entry_point, { 0xff,0xe0 } };
#endif
#include "poppack.h"
- static const char filler[0x1000];
DWORD dummy, file_align;
HANDLE file, thread, process, hmap, hmap_dup;
char temp_path[MAX_PATH], dll_name[MAX_PATH], cmdline[MAX_PATH * 2];
@@ -2603,7 +2710,7 @@
ok(!!pd->ThunkAddress, "no ThunkAddress supplied\n");
if (pd->ThunkAddress)
- ok(pd->ThunkAddress->u1.Ordinal == 0, "expected 0, got %x\n",
(UINT)pd->ThunkAddress->u1.Ordinal);
+ ok(pd->ThunkAddress->u1.Ordinal, "no ThunkAddress value
supplied\n");
ok(!!pd->TargetDllName, "no TargetDllName supplied\n");
if (pd->TargetDllName)
@@ -2628,7 +2735,6 @@
{
static const char test_dll[] = "secur32.dll";
static const char test_func[] = "SealMessage";
- static const char filler[0x1000];
char temp_path[MAX_PATH];
char dll_name[MAX_PATH];
IMAGE_DELAYLOAD_DESCRIPTOR idd, *delaydir;
@@ -2722,7 +2828,8 @@
/* sections */
section.PointerToRawData =
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress;
section.VirtualAddress =
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress;
- section.Misc.VirtualSize =
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size;
+ section.Misc.VirtualSize = 2 * sizeof(idd);
+ section.SizeOfRawData = section.Misc.VirtualSize;
section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
SetLastError(0xdeadbeef);
ret = WriteFile(hfile, §ion, sizeof(section), &dummy, NULL);
@@ -2734,18 +2841,14 @@
section.Misc.VirtualSize = sizeof(test_dll) + sizeof(hint) + sizeof(test_func) +
sizeof(HMODULE) +
2 * (i + 1) * sizeof(IMAGE_THUNK_DATA);
ok(section.Misc.VirtualSize <= 0x1000, "Too much tests, add a new
section!\n");
+ section.SizeOfRawData = section.Misc.VirtualSize;
section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
IMAGE_SCN_MEM_WRITE;
SetLastError(0xdeadbeef);
ret = WriteFile(hfile, §ion, sizeof(section), &dummy, NULL);
ok(ret, "WriteFile error %d\n", GetLastError());
/* fill up to delay data */
- file_size = GetFileSize(hfile, NULL);
- SetLastError(0xdeadbeef);
- ret = WriteFile(hfile, filler,
-
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress
- file_size,
- &dummy, NULL);
- ok(ret, "WriteFile error %d\n", GetLastError());
+ SetFilePointer( hfile,
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress,
NULL, SEEK_SET );
/* delay data */
idd.Attributes.AllAttributes = 1;
@@ -2766,10 +2869,7 @@
ok(ret, "WriteFile error %d\n", GetLastError());
/* fill up to extended delay data */
- file_size = GetFileSize(hfile, NULL);
- SetLastError(0xdeadbeef);
- ret = WriteFile(hfile, filler, idd.DllNameRVA - file_size, &dummy, NULL);
- ok(ret, "WriteFile error %d\n", GetLastError());
+ SetFilePointer( hfile, idd.DllNameRVA, NULL, SEEK_SET );
/* extended delay data */
SetLastError(0xdeadbeef);
@@ -2784,9 +2884,20 @@
ret = WriteFile(hfile, test_func, sizeof(test_func), &dummy, NULL);
ok(ret, "WriteFile error %d\n", GetLastError());
- file_size = GetFileSize(hfile, NULL);
- SetLastError(0xdeadbeef);
- ret = WriteFile(hfile, filler, idd.ImportNameTableRVA - file_size, &dummy,
NULL);
+ SetFilePointer( hfile, idd.ImportAddressTableRVA, NULL, SEEK_SET );
+
+ for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
+ {
+ /* 0x1a00 is an empty space between delay data and extended delay data, real
thunks are not necessary */
+ itd32.u1.Function = nt_header.OptionalHeader.ImageBase + 0x1a00 + i * 0x20;
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+ }
+
+ itd32.u1.Function = 0;
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL);
ok(ret, "WriteFile error %d\n", GetLastError());
for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
@@ -2806,10 +2917,8 @@
ok(ret, "WriteFile error %d\n", GetLastError());
/* fill up to eof */
- file_size = GetFileSize(hfile, NULL);
- SetLastError(0xdeadbeef);
- ret = WriteFile(hfile, filler, section.VirtualAddress + section.Misc.VirtualSize -
file_size, &dummy, NULL);
- ok(ret, "WriteFile error %d\n", GetLastError());
+ SetFilePointer( hfile, section.VirtualAddress + section.Misc.VirtualSize, NULL,
SEEK_SET );
+ SetEndOfFile( hfile );
CloseHandle(hfile);
SetLastError(0xdeadbeef);
@@ -2902,10 +3011,11 @@
{
int argc;
char **argv;
- HANDLE ntdll, mapping;
+ HANDLE ntdll, mapping, kernel32;
SYSTEM_INFO si;
ntdll = GetModuleHandleA("ntdll.dll");
+ kernel32 = GetModuleHandleA("kernel32.dll");
pNtCreateSection = (void *)GetProcAddress(ntdll, "NtCreateSection");
pNtQuerySection = (void *)GetProcAddress(ntdll, "NtQuerySection");
pNtMapViewOfSection = (void *)GetProcAddress(ntdll, "NtMapViewOfSection");
@@ -2922,7 +3032,11 @@
pRtlAcquirePebLock = (void *)GetProcAddress(ntdll, "RtlAcquirePebLock");
pRtlReleasePebLock = (void *)GetProcAddress(ntdll, "RtlReleasePebLock");
pRtlImageDirectoryEntryToData = (void *)GetProcAddress(ntdll,
"RtlImageDirectoryEntryToData");
- pResolveDelayLoadedAPI = (void
*)GetProcAddress(GetModuleHandleA("kernel32.dll"),
"ResolveDelayLoadedAPI");
+ pFlsAlloc = (void *)GetProcAddress(kernel32, "FlsAlloc");
+ pFlsSetValue = (void *)GetProcAddress(kernel32, "FlsSetValue");
+ pFlsGetValue = (void *)GetProcAddress(kernel32, "FlsGetValue");
+ pFlsFree = (void *)GetProcAddress(kernel32, "FlsFree");
+ pResolveDelayLoadedAPI = (void *)GetProcAddress(kernel32,
"ResolveDelayLoadedAPI");
GetSystemInfo( &si );
page_size = si.dwPageSize;
Modified: trunk/rostests/winetests/kernel32/locale.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/locale…
==============================================================================
--- trunk/rostests/winetests/kernel32/locale.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/locale.c [iso-8859-1] Wed Sep 7 22:32:56 2016
@@ -102,6 +102,7 @@
static BOOL (WINAPI *pGetSystemPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
static BOOL (WINAPI *pGetThreadPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
+static INT (WINAPI *pGetNumberFormatEx)(LPCWSTR, DWORD, LPCWSTR, const NUMBERFMTW *,
LPWSTR, int);
static void InitFunctionPointers(void)
{
@@ -132,6 +133,7 @@
X(EnumSystemGeoID);
X(GetSystemPreferredUILanguages);
X(GetThreadPreferredUILanguages);
+ X(GetNumberFormatEx);
mod = GetModuleHandleA("ntdll");
X(RtlUpcaseUnicodeChar);
@@ -1590,6 +1592,188 @@
ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
+ }
+}
+
+static void test_GetNumberFormatEx(void)
+{
+ int ret;
+ NUMBERFMTW format;
+ static WCHAR dotW[] = {'.',0};
+ static WCHAR commaW[] = {',',0};
+ static const WCHAR enW[] =
{'e','n','-','U','S',0};
+ static const WCHAR frW[] =
{'f','r','-','F','R',0};
+ static const WCHAR bogusW[] =
{'b','o','g','u','s',0};
+ WCHAR buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
+
+ if (!pGetNumberFormatEx)
+ {
+ win_skip("GetNumberFormatEx is not available.\n");
+ return;
+ }
+
+ STRINGSW("23",""); /* NULL output, length > 0 --> Error */
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, NULL, COUNTOF(buffer));
+ ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+ STRINGSW("23,53",""); /* Invalid character --> Error */
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+ STRINGSW("--",""); /* Double '-' --> Error */
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+ STRINGSW("0-",""); /* Trailing '-' --> Error */
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+ STRINGSW("0..",""); /* Double '.' --> Error */
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+ STRINGSW(" 0.1",""); /* Leading space --> Error */
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+ STRINGSW("1234","1"); /* Length too small --> Write up to length
chars */
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, 2);
+ ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
+
+ STRINGSW("23",""); /* Bogus locale --> Error */
+ ret = pGetNumberFormatEx(bogusW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+ memset(&format, 0, sizeof(format));
+
+ STRINGSW("2353",""); /* Format and flags given --> Error */
+ ret = pGetNumberFormatEx(enW, NUO, input, &format, buffer, COUNTOF(buffer));
+ ok( !ret, "Expected ret == 0, got %d\n", ret);
+ ok( GetLastError() == ERROR_INVALID_FLAGS || GetLastError() ==
ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
+
+ STRINGSW("2353",""); /* Invalid format --> Error */
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+ STRINGSW("2353","2,353.00"); /* Valid number */
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ STRINGSW("-2353","-2,353.00"); /* Valid negative number */
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ STRINGSW("-353","-353.00"); /* test for off by one error in
grouping */
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ STRINGSW("2353.1","2,353.10"); /* Valid real number */
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ STRINGSW("2353.111","2,353.11"); /* Too many DP --> Truncated
*/
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ STRINGSW("2353.119","2,353.12"); /* Too many DP --> Rounded */
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ format.NumDigits = 0; /* No decimal separator */
+ format.LeadingZero = 0;
+ format.Grouping = 0; /* No grouping char */
+ format.NegativeOrder = 0;
+ format.lpDecimalSep = dotW;
+ format.lpThousandSep = commaW;
+
+ STRINGSW("2353","2353"); /* No decimal or grouping chars expected
*/
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ format.NumDigits = 1; /* 1 DP --> Expect decimal separator */
+ STRINGSW("2353","2353.0");
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ format.Grouping = 2; /* Group by 100's */
+ STRINGSW("2353","23,53.0");
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ STRINGSW("235","235.0"); /* Grouping of a positive number */
+ format.Grouping = 3;
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ STRINGSW("-235","-235.0"); /* Grouping of a negative number */
+ format.NegativeOrder = NEG_LEFT;
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ format.LeadingZero = 1; /* Always provide leading zero */
+ STRINGSW(".5","0.5");
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ format.NegativeOrder = NEG_PARENS;
+ STRINGSW("-1","(1.0)");
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ format.NegativeOrder = NEG_LEFT;
+ STRINGSW("-1","-1.0");
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ format.NegativeOrder = NEG_LEFT_SPACE;
+ STRINGSW("-1","- 1.0");
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ format.NegativeOrder = NEG_RIGHT;
+ STRINGSW("-1","1.0-");
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ format.NegativeOrder = NEG_RIGHT_SPACE;
+ STRINGSW("-1","1.0 -");
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
+
+ if (pIsValidLocaleName(frW))
+ {
+ STRINGSW("-12345","-12 345,00"); /* Try French formatting */
+ Expected[3] = 160; /* Non breaking space */
+ ret = pGetNumberFormatEx(frW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
+ EXPECT_LENW; EXPECT_EQW;
}
}
@@ -4102,7 +4286,7 @@
static void test_GetLocaleInfoEx(void)
{
static const WCHAR enW[] = {'e','n',0};
- WCHAR bufferW[80];
+ WCHAR bufferW[80], buffer2[80];
INT ret;
if (!pGetLocaleInfoEx)
@@ -4173,6 +4357,12 @@
ok(!lstrcmpW(bufferW, ptr->name), "%s: got wrong LOCALE_SNAME
%s\n", wine_dbgstr_w(ptr->name), wine_dbgstr_w(bufferW));
ptr++;
}
+
+ ret = pGetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, bufferW,
sizeof(bufferW)/sizeof(WCHAR));
+ ok(ret && ret == lstrlenW(bufferW)+1, "got ret value %d\n",
ret);
+ ret = GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SNAME, buffer2,
sizeof(buffer2)/sizeof(WCHAR));
+ ok(ret && ret == lstrlenW(buffer2)+1, "got ret value %d\n",
ret);
+ ok(!lstrcmpW(bufferW, buffer2), "LOCALE_SNAMEs don't match %s
%s\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(buffer2));
}
}
@@ -4853,6 +5043,7 @@
test_GetDateFormatW();
test_GetCurrencyFormatA(); /* Also tests the W version */
test_GetNumberFormatA(); /* Also tests the W version */
+ test_GetNumberFormatEx();
test_CompareStringA();
test_CompareStringW();
test_CompareStringEx();
Modified: trunk/rostests/winetests/kernel32/path.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/path.c…
==============================================================================
--- trunk/rostests/winetests/kernel32/path.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/path.c [iso-8859-1] Wed Sep 7 22:32:56 2016
@@ -187,15 +187,8 @@
len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
if(passfail==NULL) {
ok(len, "%s: GetLongPathNameA failed\n",errstr);
- if(HAS_TRAIL_SLASH_A(fullpath)) {
- ok(lstrcmpiA(fullpathlong,tmpstr)==0,
- "%s: GetLongPathNameA returned '%s' instead of
'%s'\n",
- errstr,tmpstr,fullpathlong);
- } else {
- ok(lstrcmpiA(fullpathlong,tmpstr)==0,
- "%s: GetLongPathNameA returned '%s' instead of
'%s'\n",
- errstr,tmpstr,fullpathlong);
- }
+ ok(!lstrcmpiA(fullpathlong, tmpstr), "%s: GetLongPathNameA returned
'%s' instead of '%s'\n",
+ errstr, tmpstr, fullpathlong);
} else {
passfail->longlen=len;
passfail->longerror=GetLastError();
@@ -952,6 +945,28 @@
test_ShortPathCase(curdir,SHORTDIR,LONGFILE);
test_ShortPathCase(curdir,LONGDIR,SHORTFILE);
test_ShortPathCase(curdir,LONGDIR,LONGFILE);
+
+ /* test double delimiters */
+ sprintf(tmpstr,"%s\\\\%s", SHORTDIR,SHORTFILE);
+ ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
+ ok(lstrcmpiA(tmpstr,tmpstr1)==0,
+ "GetShortPathNameA returned '%s' instead of
'%s'\n",tmpstr1,tmpstr);
+ sprintf(tmpstr,".\\\\%s\\\\%s", SHORTDIR,SHORTFILE);
+ ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
+ ok(lstrcmpiA(tmpstr,tmpstr1)==0,
+ "GetShortPathNameA returned '%s' instead of
'%s'\n",tmpstr1,tmpstr);
+
+ if (pGetLongPathNameA) {
+ sprintf(tmpstr,"%s\\\\%s",LONGDIR,LONGFILE);
+ ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA
failed\n");
+ ok(lstrcmpiA(tmpstr,tmpstr1)==0,
+ "GetLongPathNameA returned '%s' instead of
'%s'\n",tmpstr1,tmpstr);
+
+ sprintf(tmpstr,".\\\\%s\\\\%s",LONGDIR,LONGFILE);
+ ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA
failed\n");
+ ok(lstrcmpiA(tmpstr,tmpstr1)==0,
+ "GetLongPathNameA returned '%s' instead of
'%s'\n",tmpstr1,tmpstr);
+ }
}
static void test_GetTempPathA(char* tmp_dir)
@@ -2216,6 +2231,16 @@
ok(ret, "GetShortPathName error %d\n", GetLastError());
ok(!strcmp(buf, ".\\..\\foo\\file"), "expected .\\..\\foo\\file, got
%s\n", buf);
+ /* test double delimiters */
+ strcpy(buf, "deadbeef");
+ ret = pGetLongPathNameA("..\\\\foo\\file", buf, MAX_PATH);
+ ok(ret, "GetLongPathName error %d\n", GetLastError());
+ ok(!strcmp(buf, "..\\\\foo\\file"), "expected ..\\\\foo\\file, got
%s\n", buf);
+ strcpy(buf, "deadbeef");
+ ret = GetShortPathNameA("..\\\\foo\\file", buf, MAX_PATH);
+ ok(ret, "GetShortPathName error %d\n", GetLastError());
+ ok(!strcmp(buf, "..\\\\foo\\file"), "expected ..\\\\foo\\file, got
%s\n", buf);
+
SetCurrentDirectoryA("..");
DeleteFileA("foo\\file");
RemoveDirectoryA("foo");
Modified: trunk/rostests/winetests/kernel32/thread.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/thread…
==============================================================================
--- trunk/rostests/winetests/kernel32/thread.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/thread.c [iso-8859-1] Wed Sep 7 22:32:56 2016
@@ -1318,33 +1318,64 @@
ret = pUnregisterWait(wait_handle);
ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
-}
-
-static DWORD TLS_main;
-static DWORD TLS_index0, TLS_index1;
-
-static DWORD WINAPI TLS_InheritanceProc(LPVOID p)
-{
- /* We should NOT inherit the TLS values from our parent or from the
+
+ SetLastError(0xdeadbeef);
+ ret = pUnregisterWait(NULL);
+ ok(!ret, "Expected UnregisterWait to fail\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE,
+ "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
+}
+
+static DWORD LS_main;
+static DWORD LS_index0, LS_index1;
+static DWORD LS_OutOfIndexesValue;
+
+/* Function pointers to the FLS/TLS functions to test in LS_ThreadProc() */
+static DWORD (WINAPI *LS_AllocFunc)(void);
+static PVOID (WINAPI *LS_GetValueFunc)(DWORD);
+static BOOL (WINAPI *LS_SetValueFunc)(DWORD, PVOID);
+static BOOL (WINAPI *LS_FreeFunc)(DWORD);
+
+/* Names of the functions tested in LS_ThreadProc(), for error messages */
+static const char* LS_AllocFuncName = "";
+static const char* LS_GetValueFuncName = "";
+static const char* LS_SetValueFuncName = "";
+static const char* LS_FreeFuncName = "";
+
+/* FLS entry points, dynamically loaded in platforms that support them */
+static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION);
+static BOOL (WINAPI *pFlsFree)(DWORD);
+static PVOID (WINAPI *pFlsGetValue)(DWORD);
+static BOOL (WINAPI *pFlsSetValue)(DWORD,PVOID);
+
+/* A thunk function to make FlsAlloc compatible with the signature of TlsAlloc */
+static DWORD WINAPI FLS_AllocFuncThunk(void)
+{
+ return pFlsAlloc(NULL);
+}
+
+static DWORD WINAPI LS_InheritanceProc(LPVOID p)
+{
+ /* We should NOT inherit the FLS/TLS values from our parent or from the
main thread. */
LPVOID val;
- val = TlsGetValue(TLS_main);
- ok(val == NULL, "TLS inheritance failed\n");
-
- val = TlsGetValue(TLS_index0);
- ok(val == NULL, "TLS inheritance failed\n");
-
- val = TlsGetValue(TLS_index1);
- ok(val == NULL, "TLS inheritance failed\n");
+ val = LS_GetValueFunc(LS_main);
+ ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
+
+ val = LS_GetValueFunc(LS_index0);
+ ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
+
+ val = LS_GetValueFunc(LS_index1);
+ ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
return 0;
}
-/* Basic TLS usage test. Make sure we can create slots and the values we
- store in them are separate among threads. Also test TLS value
- inheritance with TLS_InheritanceProc. */
-static DWORD WINAPI TLS_ThreadProc(LPVOID p)
+/* Basic FLS/TLS usage test. Make sure we can create slots and the values we
+ store in them are separate among threads. Also test FLS/TLS value
+ inheritance with LS_InheritanceProc. */
+static DWORD WINAPI LS_ThreadProc(LPVOID p)
{
LONG_PTR id = (LONG_PTR) p;
LPVOID val;
@@ -1352,80 +1383,80 @@
if (sync_threads_and_run_one(0, id))
{
- TLS_index0 = TlsAlloc();
- ok(TLS_index0 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
+ LS_index0 = LS_AllocFunc();
+ ok(LS_index0 != LS_OutOfIndexesValue, "%s failed\n", LS_AllocFuncName);
}
resync_after_run();
if (sync_threads_and_run_one(1, id))
{
- TLS_index1 = TlsAlloc();
- ok(TLS_index1 != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
+ LS_index1 = LS_AllocFunc();
+ ok(LS_index1 != LS_OutOfIndexesValue, "%s failed\n", LS_AllocFuncName);
/* Slot indices should be different even if created in different
threads. */
- ok(TLS_index0 != TLS_index1, "TlsAlloc failed\n");
+ ok(LS_index0 != LS_index1, "%s failed\n", LS_AllocFuncName);
/* Both slots should be initialized to NULL */
- val = TlsGetValue(TLS_index0);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == NULL, "TLS slot not initialized correctly\n");
-
- val = TlsGetValue(TLS_index1);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == NULL, "TLS slot not initialized correctly\n");
+ val = LS_GetValueFunc(LS_index0);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == NULL, "Slot not initialized correctly\n");
+
+ val = LS_GetValueFunc(LS_index1);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == NULL, "Slot not initialized correctly\n");
}
resync_after_run();
if (sync_threads_and_run_one(0, id))
{
- val = TlsGetValue(TLS_index0);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == NULL, "TLS slot not initialized correctly\n");
-
- val = TlsGetValue(TLS_index1);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == NULL, "TLS slot not initialized correctly\n");
-
- ret = TlsSetValue(TLS_index0, (LPVOID) 1);
- ok(ret, "TlsSetValue failed\n");
-
- ret = TlsSetValue(TLS_index1, (LPVOID) 2);
- ok(ret, "TlsSetValue failed\n");
-
- val = TlsGetValue(TLS_index0);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
-
- val = TlsGetValue(TLS_index1);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
+ val = LS_GetValueFunc(LS_index0);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == NULL, "Slot not initialized correctly\n");
+
+ val = LS_GetValueFunc(LS_index1);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == NULL, "Slot not initialized correctly\n");
+
+ ret = LS_SetValueFunc(LS_index0, (LPVOID) 1);
+ ok(ret, "%s failed\n", LS_SetValueFuncName);
+
+ ret = LS_SetValueFunc(LS_index1, (LPVOID) 2);
+ ok(ret, "%s failed\n", LS_SetValueFuncName);
+
+ val = LS_GetValueFunc(LS_index0);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == (LPVOID) 1, "Slot not initialized correctly\n");
+
+ val = LS_GetValueFunc(LS_index1);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == (LPVOID) 2, "Slot not initialized correctly\n");
}
resync_after_run();
if (sync_threads_and_run_one(1, id))
{
- val = TlsGetValue(TLS_index0);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == NULL, "TLS slot not initialized correctly\n");
-
- val = TlsGetValue(TLS_index1);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == NULL, "TLS slot not initialized correctly\n");
-
- ret = TlsSetValue(TLS_index0, (LPVOID) 3);
- ok(ret, "TlsSetValue failed\n");
-
- ret = TlsSetValue(TLS_index1, (LPVOID) 4);
- ok(ret, "TlsSetValue failed\n");
-
- val = TlsGetValue(TLS_index0);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == (LPVOID) 3, "TLS slot not initialized correctly\n");
-
- val = TlsGetValue(TLS_index1);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == (LPVOID) 4, "TLS slot not initialized correctly\n");
+ val = LS_GetValueFunc(LS_index0);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == NULL, "Slot not initialized correctly\n");
+
+ val = LS_GetValueFunc(LS_index1);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == NULL, "Slot not initialized correctly\n");
+
+ ret = LS_SetValueFunc(LS_index0, (LPVOID) 3);
+ ok(ret, "%s failed\n", LS_SetValueFuncName);
+
+ ret = LS_SetValueFunc(LS_index1, (LPVOID) 4);
+ ok(ret, "%s failed\n", LS_SetValueFuncName);
+
+ val = LS_GetValueFunc(LS_index0);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == (LPVOID) 3, "Slot not initialized correctly\n");
+
+ val = LS_GetValueFunc(LS_index1);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == (LPVOID) 4, "Slot not initialized correctly\n");
}
resync_after_run();
@@ -1434,36 +1465,36 @@
HANDLE thread;
DWORD waitret, tid;
- val = TlsGetValue(TLS_index0);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == (LPVOID) 1, "TLS slot not initialized correctly\n");
-
- val = TlsGetValue(TLS_index1);
- ok(GetLastError() == ERROR_SUCCESS, "TlsGetValue failed\n");
- ok(val == (LPVOID) 2, "TLS slot not initialized correctly\n");
-
- thread = CreateThread(NULL, 0, TLS_InheritanceProc, 0, 0, &tid);
+ val = LS_GetValueFunc(LS_index0);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == (LPVOID) 1, "Slot not initialized correctly\n");
+
+ val = LS_GetValueFunc(LS_index1);
+ ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
+ ok(val == (LPVOID) 2, "Slot not initialized correctly\n");
+
+ thread = CreateThread(NULL, 0, LS_InheritanceProc, 0, 0, &tid);
ok(thread != NULL, "CreateThread failed\n");
waitret = WaitForSingleObject(thread, 60000);
ok(waitret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
CloseHandle(thread);
- ret = TlsFree(TLS_index0);
- ok(ret, "TlsFree failed\n");
+ ret = LS_FreeFunc(LS_index0);
+ ok(ret, "%s failed\n", LS_FreeFuncName);
}
resync_after_run();
if (sync_threads_and_run_one(1, id))
{
- ret = TlsFree(TLS_index1);
- ok(ret, "TlsFree failed\n");
+ ret = LS_FreeFunc(LS_index1);
+ ok(ret, "%s failed\n", LS_FreeFuncName);
}
resync_after_run();
return 0;
}
-static void test_TLS(void)
+static void run_LS_tests(void)
{
HANDLE threads[2];
LONG_PTR i;
@@ -1472,17 +1503,17 @@
init_thread_sync_helpers();
- /* Allocate a TLS slot in the main thread to test for inheritance. */
- TLS_main = TlsAlloc();
- ok(TLS_main != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
- suc = TlsSetValue(TLS_main, (LPVOID) 4114);
- ok(suc, "TlsSetValue failed\n");
+ /* Allocate a slot in the main thread to test for inheritance. */
+ LS_main = LS_AllocFunc();
+ ok(LS_main != LS_OutOfIndexesValue, "%s failed\n", LS_AllocFuncName);
+ suc = LS_SetValueFunc(LS_main, (LPVOID) 4114);
+ ok(suc, "%s failed\n", LS_SetValueFuncName);
for (i = 0; i < 2; ++i)
{
DWORD tid;
- threads[i] = CreateThread(NULL, 0, TLS_ThreadProc, (LPVOID) i, 0, &tid);
+ threads[i] = CreateThread(NULL, 0, LS_ThreadProc, (LPVOID) i, 0, &tid);
ok(threads[i] != NULL, "CreateThread failed\n");
}
@@ -1492,9 +1523,49 @@
for (i = 0; i < 2; ++i)
CloseHandle(threads[i]);
- suc = TlsFree(TLS_main);
- ok(suc, "TlsFree failed\n");
+ suc = LS_FreeFunc(LS_main);
+ ok(suc, "%s failed\n", LS_FreeFuncName);
cleanup_thread_sync_helpers();
+}
+
+static void test_TLS(void)
+{
+ LS_OutOfIndexesValue = TLS_OUT_OF_INDEXES;
+
+ LS_AllocFunc = &TlsAlloc;
+ LS_GetValueFunc = &TlsGetValue;
+ LS_SetValueFunc = &TlsSetValue;
+ LS_FreeFunc = &TlsFree;
+
+ LS_AllocFuncName = "TlsAlloc";
+ LS_GetValueFuncName = "TlsGetValue";
+ LS_SetValueFuncName = "TlsSetValue";
+ LS_FreeFuncName = "TlsFree";
+
+ run_LS_tests();
+}
+
+static void test_FLS(void)
+{
+ if (!pFlsAlloc || !pFlsFree || !pFlsGetValue || !pFlsSetValue)
+ {
+ win_skip("Fiber Local Storage not supported\n");
+ return;
+ }
+
+ LS_OutOfIndexesValue = FLS_OUT_OF_INDEXES;
+
+ LS_AllocFunc = &FLS_AllocFuncThunk;
+ LS_GetValueFunc = pFlsGetValue;
+ LS_SetValueFunc = pFlsSetValue;
+ LS_FreeFunc = pFlsFree;
+
+ LS_AllocFuncName = "FlsAlloc";
+ LS_GetValueFuncName = "FlsGetValue";
+ LS_SetValueFuncName = "FlsSetValue";
+ LS_FreeFuncName = "FlsFree";
+
+ run_LS_tests();
}
static void test_ThreadErrorMode(void)
@@ -2018,6 +2089,11 @@
X(GetThreadGroupAffinity);
X(SetThreadGroupAffinity);
+
+ X(FlsAlloc);
+ X(FlsFree);
+ X(FlsSetValue);
+ X(FlsGetValue);
#undef X
#define X(f) p##f = (void*)GetProcAddress(ntdll, #f)
@@ -2085,6 +2161,7 @@
test_QueueUserWorkItem();
test_RegisterWaitForSingleObject();
test_TLS();
+ test_FLS();
test_ThreadErrorMode();
#if (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) ||
(defined(_MSC_VER) && defined(__i386__))
test_thread_fpu_cw();
Modified: trunk/rostests/winetests/kernel32/virtual.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/virtua…
==============================================================================
--- trunk/rostests/winetests/kernel32/virtual.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/virtual.c [iso-8859-1] Wed Sep 7 22:32:56 2016
@@ -2799,10 +2799,7 @@
ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
ok( ret == 43, "call returned wrong result, expected 43, got %d\n", ret );
ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION
exception, got %d exceptions\n", num_guard_page_calls );
- if ((dep_flags & MEM_EXECUTE_OPTION_DISABLE) && (dep_flags &
MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION))
- ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION
exception, got %d exceptions\n", num_execute_fault_calls );
- else
- ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION
exception, got %d exceptions\n", num_execute_fault_calls );
+ ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION
exception, got %d exceptions\n", num_execute_fault_calls );
/* Now a bit more complicated, the page containing the code is protected with
* PAGE_GUARD memory protection. */
@@ -4109,14 +4106,7 @@
}
if (!strcmp(argv[2], "sharedmemro"))
{
- if(!winetest_interactive)
- {
- skip("CORE-8541: Skipping test_shared_memory_ro(TRUE,
strtol(argv[3], NULL, 16))\n");
- }
- else
- {
- test_shared_memory_ro(TRUE, strtol(argv[3], NULL, 16));
- }
+ test_shared_memory_ro(TRUE, strtol(argv[3], NULL, 16));
return;
}
while (1)