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. The service will catch up by going through the existing process list on startup.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=29168 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 | 75 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index b62239de5b4..bd4caef5d0c 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -202,6 +202,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 d6b9b2ff0ab..dcd1d44e3d8 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -1490,6 +1490,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 6ce56f39fd8..df08d2c972d 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 6baeb610fc4..3e5993d369c 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -46,10 +46,13 @@ #include "wine/server.h" #include "wine/debug.h" #include "ntdll_misc.h" +#include "wine/unicode.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 +215,78 @@ static void set_process_name( int argc, char *argv[] ) #endif /* HAVE_PRCTL */ }
+void user_shared_data_init(void) +{ + static const WCHAR directory_nameW[] = {'\','D','e','v','i','c','e','\','W','i','n','e','U','s','d',0}; + static const WCHAR device_nameW[] = {'\','D','e','v','i','c','e','\','W','i','n','e','U','s','d','\','C','o','n','t','r','o','l',0}; + static const WCHAR section_formatW[] = {'\','D','e','v','i','c','e','\','W','i','n','e','U','s','d','\','%','0','8','x',0}; + OBJECT_ATTRIBUTES attr = {sizeof(attr)}; + IO_STATUS_BLOCK io; + UNICODE_STRING string; + NTSTATUS status; + HANDLE directory, section, device; + WCHAR section_nameW[64]; + + struct _KUSER_SHARED_DATA tmp; + LARGE_INTEGER section_size; + SIZE_T size = 0x10000; + void *addr; + + section_size.HighPart = 0; + section_size.LowPart = size; + + RtlInitUnicodeString( &string, directory_nameW ); + InitializeObjectAttributes( &attr, &string, 0, NULL, NULL ); + if ((status = NtCreateDirectoryObject( &directory, 0, &attr )) && status != STATUS_OBJECT_NAME_COLLISION) + WARN_(wineusd)( "Failed to create directory, status: %x\n", status ); + + sprintfW( section_nameW, section_formatW, GetCurrentProcessId() ); + RtlInitUnicodeString( &string, section_nameW ); + InitializeObjectAttributes( &attr, &string, 0, NULL, NULL ); + if ((status = NtCreateSection( §ion, SECTION_ALL_ACCESS, &attr, §ion_size, + PAGE_READWRITE, SEC_COMMIT, NULL ))) + { + WARN_(wineusd)( "Failed to create section, status: %x\n", status ); + return; + } + + NtClose( directory ); + + addr = (void *)user_shared_data; + size = 0; + tmp = *user_shared_data; + if ((status = NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ))) + { + ERR_(wineusd)( "Failed to release memory, status: %x\n", status ); + NtClose( section ); + return; + } + + addr = (void *)user_shared_data; + size = 0; + if ((status = NtMapViewOfSection( section, NtCurrentProcess(), &addr, 0, 0, 0, + &size, ViewShare, 0, PAGE_READWRITE ))) + { + WARN_(wineusd)( "wine: failed to map section, status: %x\n", status ); + NtClose( section ); + + if ((status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size, + MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE ))) + { + MESSAGE( "wine: failed to remap the user shared data: %08x\n", status ); + exit(1); + } + } + user_shared_data = addr; + *user_shared_data = tmp; + + RtlInitUnicodeString( &string, device_nameW ); + InitializeObjectAttributes( &attr, &string, 0, NULL, NULL ); + 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 device, status: %x\n", status ); +}
/*********************************************************************** * thread_init