Patch from: Andrew Wesie awesie@gmail.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/tests/time.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c index 5382a952d8d..be6859fe3e1 100644 --- a/dlls/ntdll/tests/time.c +++ b/dlls/ntdll/tests/time.c @@ -18,7 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#define NONAMELESSUNION #include "ntdll_test.h" +#include "ddk/wdm.h"
#define TICKSPERSEC 10000000 #define TICKSPERMSEC 10000 @@ -29,6 +31,7 @@ static VOID (WINAPI *pRtlTimeFieldsToTime)( PTIME_FIELDS TimeFields, PLARGE_IN static NTSTATUS (WINAPI *pNtQueryPerformanceCounter)( LARGE_INTEGER *counter, LARGE_INTEGER *frequency ); static NTSTATUS (WINAPI *pRtlQueryTimeZoneInformation)( RTL_TIME_ZONE_INFORMATION *); static NTSTATUS (WINAPI *pRtlQueryDynamicTimeZoneInformation)( RTL_DYNAMIC_TIME_ZONE_INFORMATION *); +static ULONG (WINAPI *pNtGetTickCount)(void);
static const int MonthLengths[2][12] = { @@ -153,12 +156,35 @@ static void test_RtlQueryTimeZoneInformation(void) wine_dbgstr_w(tzinfo.DaylightName)); }
+static void test_NtGetTickCount(void) +{ + KSHARED_USER_DATA *user_shared_data = (void *)0x7ffe0000; + LONG diff; + int i; + + if (!pNtGetTickCount) + { + win_skip("NtGetTickCount is not available\n"); + return; + } + + for (i = 0; i < 5; ++i) + { + diff = (user_shared_data->u.TickCountQuad * user_shared_data->TickCountMultiplier) >> 24; + diff = pNtGetTickCount() - diff; + todo_wine + ok(diff < 100, "NtGetTickCount - TickCountQuad too high, expected < 100 got %d\n", diff); + Sleep(50); + } +} + START_TEST(time) { HMODULE mod = GetModuleHandleA("ntdll.dll"); pRtlTimeToTimeFields = (void *)GetProcAddress(mod,"RtlTimeToTimeFields"); pRtlTimeFieldsToTime = (void *)GetProcAddress(mod,"RtlTimeFieldsToTime"); pNtQueryPerformanceCounter = (void *)GetProcAddress(mod, "NtQueryPerformanceCounter"); + pNtGetTickCount = (void *)GetProcAddress(mod,"NtGetTickCount"); pRtlQueryTimeZoneInformation = (void *)GetProcAddress(mod, "RtlQueryTimeZoneInformation"); pRtlQueryDynamicTimeZoneInformation = @@ -169,5 +195,6 @@ START_TEST(time) else win_skip("Required time conversion functions are not available\n"); test_NtQueryPerformanceCounter(); + test_NtGetTickCount(); test_RtlQueryTimeZoneInformation(); }
This service is started at boot, and hopefully before any process that might rely on the timestamp update. If the service is not yet started, then the opening the device will fail and the process should continue and use its private user shared data instead.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- configure.ac | 1 + dlls/wineusd.sys/Makefile.in | 6 + dlls/wineusd.sys/wineusd.sys.spec | 1 + dlls/wineusd.sys/wineusd_main.c | 274 ++++++++++++++++++++++++++++++ include/wine/usd.h | 27 +++ loader/wine.inf.in | 12 ++ 6 files changed, 321 insertions(+) create mode 100644 dlls/wineusd.sys/Makefile.in create mode 100644 dlls/wineusd.sys/wineusd.sys.spec create mode 100644 dlls/wineusd.sys/wineusd_main.c create mode 100644 include/wine/usd.h
diff --git a/configure.ac b/configure.ac index 36f65378a44..f6e86478897 100644 --- a/configure.ac +++ b/configure.ac @@ -3772,6 +3772,7 @@ WINE_CONFIG_MAKEFILE(dlls/wineps.drv) WINE_CONFIG_MAKEFILE(dlls/wineps16.drv16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/winepulse.drv) WINE_CONFIG_MAKEFILE(dlls/wineqtdecoder) +WINE_CONFIG_MAKEFILE(dlls/wineusd.sys) WINE_CONFIG_MAKEFILE(dlls/winevulkan) WINE_CONFIG_MAKEFILE(dlls/winex11.drv) WINE_CONFIG_MAKEFILE(dlls/wing.dll16,enable_win16) diff --git a/dlls/wineusd.sys/Makefile.in b/dlls/wineusd.sys/Makefile.in new file mode 100644 index 00000000000..0792860c09b --- /dev/null +++ b/dlls/wineusd.sys/Makefile.in @@ -0,0 +1,6 @@ +MODULE = wineusd.sys +IMPORTS = ntoskrnl +EXTRADLLFLAGS = -Wl,--subsystem,native -mno-cygwin + +C_SRCS = \ + wineusd_main.c diff --git a/dlls/wineusd.sys/wineusd.sys.spec b/dlls/wineusd.sys/wineusd.sys.spec new file mode 100644 index 00000000000..76421d7e35b --- /dev/null +++ b/dlls/wineusd.sys/wineusd.sys.spec @@ -0,0 +1 @@ +# nothing to export diff --git a/dlls/wineusd.sys/wineusd_main.c b/dlls/wineusd.sys/wineusd_main.c new file mode 100644 index 00000000000..f4f1132e24c --- /dev/null +++ b/dlls/wineusd.sys/wineusd_main.c @@ -0,0 +1,274 @@ +/* + * User shared data update service + * + * Copyright 2019 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <assert.h> +#include <stdarg.h> +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "winternl.h" +#include "winioctl.h" +#include "ddk/wdm.h" +#include "wine/debug.h" +#include "wine/heap.h" +#include "wine/usd.h" +#include "wine/list.h" + +static DEVICE_OBJECT *device_obj; + +WINE_DEFAULT_DEBUG_CHANNEL(wineusd); + +#define DECLARE_CRITICAL_SECTION(cs) \ + static CRITICAL_SECTION cs; \ + static CRITICAL_SECTION_DEBUG cs##_debug = \ + { 0, 0, &cs, { &cs##_debug.ProcessLocksList, &cs##_debug.ProcessLocksList }, \ + 0, 0, { (DWORD_PTR)(__FILE__ ": " # cs) }}; \ + static CRITICAL_SECTION cs = { &cs##_debug, -1, 0, 0, 0, 0 }; + +DECLARE_CRITICAL_SECTION(wineusd_cs); + +static struct list wineusd_entries = LIST_INIT(wineusd_entries); +static HANDLE wineusd_thread, wineusd_thread_stop; + +struct wineusd_entry +{ + struct list link; + CLIENT_ID cid; + HANDLE process; + HANDLE section; + void *page; +}; + +static DWORD WINAPI wineusd_thread_proc(void *arg) +{ + struct wineusd_entry *entry; + ULARGE_INTEGER interrupt; + ULARGE_INTEGER tick; + LARGE_INTEGER now; + + TRACE("Started user shared data thread.\n"); + + while (WaitForSingleObject(wineusd_thread_stop, 16) == WAIT_TIMEOUT) + { + EnterCriticalSection(&wineusd_cs); + + NtQuerySystemTime(&now); + RtlQueryUnbiasedInterruptTime(&interrupt.QuadPart); + + tick = interrupt; + tick.QuadPart /= 10000; + + LIST_FOR_EACH_ENTRY(entry, &wineusd_entries, struct wineusd_entry, link) + { + KSHARED_USER_DATA *usd = entry->page; + + usd->SystemTime.High2Time = now.u.HighPart; + usd->SystemTime.LowPart = now.u.LowPart; + usd->SystemTime.High1Time = now.u.HighPart; + + usd->InterruptTime.High2Time = interrupt.HighPart; + usd->InterruptTime.LowPart = interrupt.LowPart; + usd->InterruptTime.High1Time = interrupt.HighPart; + + usd->TickCount.High2Time = tick.HighPart; + usd->TickCount.LowPart = tick.LowPart; + usd->TickCount.High1Time = tick.HighPart; + usd->TickCountLowDeprecated = tick.LowPart; + usd->TickCountMultiplier = 1 << 24; + } + + LeaveCriticalSection(&wineusd_cs); + } + + TRACE("Stopped user shared data thread.\n"); + + return 0; +} + +static NTSTATUS wineusd_initialize(struct wineusd_entry *entry, IRP *irp) +{ + const KSHARED_USER_DATA *init = irp->AssociatedIrp.SystemBuffer; + void *user_shared_data_address = (void *)0x7ffe0000; + NTSTATUS status = STATUS_SUCCESS; + LARGE_INTEGER section_size; + SIZE_T view_size; + + entry->cid.UniqueProcess = PsGetCurrentProcessId(); + entry->cid.UniqueThread = (HANDLE)0; + if ((status = NtOpenProcess(&entry->process, PROCESS_VM_OPERATION, NULL, &entry->cid))) + { + ERR("Failed to open target process, status: %x.\n", status); + return status; + } + + section_size.HighPart = 0; + section_size.LowPart = 0x10000; + if ((status = NtCreateSection(&entry->section, SECTION_ALL_ACCESS, NULL, §ion_size, + PAGE_READWRITE, SEC_COMMIT, NULL))) + { + ERR("Failed to create section, status: %x.\n", status); + return status; + } + + view_size = 0; + if ((status = NtMapViewOfSection(entry->section, NtCurrentProcess(), &entry->page, 0, 0, 0, + &view_size, ViewShare, 0, PAGE_READWRITE))) + { + ERR("Failed to map section to driver memory, status: %x.\n", status); + return status; + } + memcpy(entry->page, init, sizeof(*init)); + + view_size = 0; + if ((status = NtMapViewOfSection(entry->section, entry->process, &user_shared_data_address, 0, 0, 0, + &view_size, ViewShare, 0, PAGE_READONLY))) + { + ERR("Failed to map user shared data to target process, status: %x.\n", status); + return status; + } + + EnterCriticalSection(&wineusd_cs); + list_add_head(&wineusd_entries, &entry->link); + LeaveCriticalSection(&wineusd_cs); + + TRACE("Initialized user shared data for process %04x.\n", HandleToULong(PsGetCurrentProcessId())); + + return STATUS_SUCCESS; +} + +static void wineusd_close(struct wineusd_entry *entry) +{ + void *user_shared_data_address = (void *)0x7ffe0000; + + TRACE("Closing user shared data for process %04x.\n", HandleToULong(entry->cid.UniqueProcess)); + + EnterCriticalSection(&wineusd_cs); + list_remove(&entry->link); + LeaveCriticalSection(&wineusd_cs); + + NtUnmapViewOfSection(entry->process, user_shared_data_address); + NtUnmapViewOfSection(NtCurrentProcess(), entry->page); + + NtClose(entry->section); + NtClose(entry->process); + heap_free(entry); +} + +static NTSTATUS WINAPI wineusd_dispatch_create(DEVICE_OBJECT *device, IRP *irp) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + struct wineusd_entry *entry; + NTSTATUS status; + + status = STATUS_NO_MEMORY; + if (!(entry = heap_alloc_zero(sizeof(*entry)))) + { + ERR("Failed to allocate memory.\n"); + goto done; + } + stack->FileObject->FsContext = entry; + + list_init(&entry->link); + entry->process = INVALID_HANDLE_VALUE; + entry->section = INVALID_HANDLE_VALUE; + entry->page = NULL; + + TRACE("Created user shared data for process %04x.\n", HandleToULong(PsGetCurrentProcessId())); + +done: + irp->IoStatus.Status = status; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return status; +} + +static NTSTATUS WINAPI wineusd_dispatch_close(DEVICE_OBJECT *device, IRP *irp) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + struct wineusd_entry *entry = stack->FileObject->FsContext; + + if (entry) wineusd_close(entry); + + irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +static NTSTATUS WINAPI wineusd_dispatch_ioctl(DEVICE_OBJECT *device, IRP *irp) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + struct wineusd_entry *entry = stack->FileObject->FsContext; + NTSTATUS ret; + + switch (stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_WINEUSD_INITIALIZE: + ret = wineusd_initialize(entry, irp); + break; + default: + FIXME("Unhandled ioctl %#x.\n", stack->Parameters.DeviceIoControl.IoControlCode); + ret = STATUS_NOT_IMPLEMENTED; + break; + } + + irp->IoStatus.Status = ret; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return ret; +} + +static void WINAPI wineusd_unload(DRIVER_OBJECT *driver) +{ + struct wineusd_entry *entry, *cursor; + + SetEvent(wineusd_thread_stop); + WaitForSingleObject(wineusd_thread, INFINITE); + CloseHandle(wineusd_thread); + CloseHandle(wineusd_thread_stop); + + LIST_FOR_EACH_ENTRY_SAFE(entry, cursor, &wineusd_entries, struct wineusd_entry, link) + wineusd_close(entry); + + IoDeleteDevice(device_obj); +} + +NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path) +{ + static const WCHAR device_nameW[] = {'\','D','e','v','i','c','e','\','W','i','n','e','U','s','d',0}; + OBJECT_ATTRIBUTES attr = {sizeof(attr)}; + UNICODE_STRING string; + NTSTATUS ret; + + TRACE("Driver %p, path %s.\n", driver, debugstr_w(path->Buffer)); + + RtlInitUnicodeString(&string, device_nameW); + if ((ret = IoCreateDevice(driver, 0, &string, FILE_DEVICE_UNKNOWN, 0, FALSE, &device_obj))) + { + ERR("Failed to create user shared data device, status %#x.\n", ret); + return ret; + } + + driver->MajorFunction[IRP_MJ_CREATE] = wineusd_dispatch_create; + driver->MajorFunction[IRP_MJ_CLOSE] = wineusd_dispatch_close; + driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = wineusd_dispatch_ioctl; + driver->DriverUnload = wineusd_unload; + + wineusd_thread_stop = CreateEventW(NULL, FALSE, FALSE, NULL); + wineusd_thread = CreateThread(NULL, 0, wineusd_thread_proc, NULL, 0, NULL); + + return STATUS_SUCCESS; +} diff --git a/include/wine/usd.h b/include/wine/usd.h new file mode 100644 index 00000000000..e92efa5e29e --- /dev/null +++ b/include/wine/usd.h @@ -0,0 +1,27 @@ +/* + * Copyright 2019 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINE_USD_H +#define __WINE_WINE_USD_H + +#include <windef.h> +#include <winioctl.h> + +#define IOCTL_WINEUSD_INITIALIZE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#endif /* __WINE_WINE_USD_H */ diff --git a/loader/wine.inf.in b/loader/wine.inf.in index 5f9f61e2535..8bccc0e068d 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -161,6 +161,7 @@ AddService=FontCache3.0.0.0,0,WPFFontCacheService AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService +AddService=WineUsd,0,WineUsdService AddService=Winmgmt,0,WinmgmtService AddService=wuauserv,0,wuauService
@@ -178,6 +179,7 @@ AddService=FontCache3.0.0.0,0,WPFFontCacheService AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService +AddService=WineUsd,0,WineUsdService AddService=Winmgmt,0,WinmgmtService AddService=wuauserv,0,wuauService
@@ -195,6 +197,7 @@ AddService=FontCache3.0.0.0,0,WPFFontCacheService AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService +AddService=WineUsd,0,WineUsdService AddService=Winmgmt,0,WinmgmtService AddService=wuauserv,0,wuauService
@@ -212,6 +215,7 @@ AddService=FontCache3.0.0.0,0,WPFFontCacheService AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService +AddService=WineUsd,0,WineUsdService AddService=Winmgmt,0,WinmgmtService AddService=wuauserv,0,wuauService
@@ -3648,6 +3652,14 @@ ServiceType=32 StartType=3 ErrorControl=1
+[WineUsdService] +Description="User shared data update service" +DisplayName="Wine User Shared Data" +ServiceBinary="%12%\WineUsd.sys" +ServiceType=1 +StartType=0 +ErrorControl=1 + [WinmgmtService] Description="Provides access to Windows Management Instrumentation" DisplayName="Windows Management Instrumentation Service"
If the device cannot be opened, then the service may not be started yet, or the current process is the service itself. In which case, we can ignore the error and continue as before without timestamp updates.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Notes: When submitting the patch on testbot, the service was not started and the test failed. It may be the same there and I think the wine.inf update requires a server restart to be accounted for. I'm not sure how to force the new service to start right away.
dlls/ntdll/ntdll_misc.h | 1 + dlls/ntdll/server.c | 2 ++ dlls/ntdll/tests/time.c | 1 - dlls/ntdll/thread.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index e1fb1e9eba7..3ef4bf5a88a 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -197,6 +197,7 @@ extern void virtual_set_large_address_space(void) DECLSPEC_HIDDEN; extern void virtual_fill_image_information( const pe_image_info_t *pe_info, SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN; extern struct _KUSER_SHARED_DATA *user_shared_data DECLSPEC_HIDDEN; +extern void user_shared_data_init(void);
/* completion */ extern NTSTATUS NTDLL_AddCompletion( HANDLE hFile, ULONG_PTR CompletionValue, diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index 089eb3b89aa..1fc902b1f29 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -1471,6 +1471,8 @@ void server_init_process_done(void) } SERVER_END_REQ;
+ user_shared_data_init(); + assert( !status ); signal_start_process( entry, suspend ); } diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c index be6859fe3e1..3c5fbbb857d 100644 --- a/dlls/ntdll/tests/time.c +++ b/dlls/ntdll/tests/time.c @@ -172,7 +172,6 @@ static void test_NtGetTickCount(void) { diff = (user_shared_data->u.TickCountQuad * user_shared_data->TickCountMultiplier) >> 24; diff = pNtGetTickCount() - diff; - todo_wine ok(diff < 100, "NtGetTickCount - TickCountQuad too high, expected < 100 got %d\n", diff); Sleep(50); } diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index f993dd314c3..8895d4f790e 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -46,10 +46,12 @@ #include "wine/server.h" #include "wine/debug.h" #include "ntdll_misc.h" +#include "wine/usd.h" #include "ddk/wdm.h" #include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(thread); +WINE_DECLARE_DEBUG_CHANNEL(wineusd);
#ifndef PTHREAD_STACK_MIN #define PTHREAD_STACK_MIN 16384 @@ -212,6 +214,38 @@ static void set_process_name( int argc, char *argv[] ) #endif /* HAVE_PRCTL */ }
+void user_shared_data_init(void) +{ + static const WCHAR device_nameW[] = {'\','D','e','v','i','c','e','\','W','i','n','e','U','s','d',0}; + struct _KUSER_SHARED_DATA data = *user_shared_data; + OBJECT_ATTRIBUTES attr = {sizeof(attr)}; + UNICODE_STRING string; + IO_STATUS_BLOCK io; + NTSTATUS status; + HANDLE device; + void *addr = user_shared_data; + SIZE_T size = 0; + + RtlInitUnicodeString( &string, device_nameW ); + attr.ObjectName = &string; + if ((status = NtCreateFile( &device, 0, &attr, &io, NULL, + FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, + FILE_NON_DIRECTORY_FILE, NULL, 0 ))) + { + WARN_(wineusd)( "Failed to open user shared data device, status: %x.\n", status ); + return; + } + + NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); + + if ((status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, + IOCTL_WINEUSD_INITIALIZE, + &data, sizeof(data), NULL, 0 ))) + { + MESSAGE( "wine: failed to map the shared user data: %08x\n", status ); + exit(1); + } +}
/*********************************************************************** * thread_init
This patch series have been released in Proton 5.0 to fix a few games that do not start if the timestamps aren't updated frequently enough (Batman AK and Just Cause 3 at least).
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=64792
Your paranoid android.
=== debian10 (32 bit report) ===
ntdll: time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441359 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441309 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441259 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441209 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441158
=== debian10 (32 bit French report) ===
ntdll: time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441359 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441309 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441259 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441209 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441159
=== debian10 (32 bit Japanese:Japan report) ===
ntdll: time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441352 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441302 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441252 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441202 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441152
=== debian10 (32 bit Chinese:China report) ===
ntdll: time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441356 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441306 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441256 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441206 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529441156
=== debian10 (32 bit WoW report) ===
ntdll: time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343571 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343521 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343471 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343421 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343371
=== debian10 (64 bit WoW report) ===
ntdll: time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343558 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343508 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343457 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343407 time.c:176: Test succeeded inside todo block: NtGetTickCount - TickCountQuad too high, expected < 100 got -1529343357