[4/5] ntdll: prevent thread suspend inside critical sections

Thomas Kho tkho at ucla.edu
Fri Aug 18 03:25:49 CDT 2006


[4/5] ntdll: prevent thread suspend inside critical sections

This patch causes SIGUSR1 to be blocked inside ntdll critical sections to
ensure integrity of critical sections if remote operations are to be executed
inside the suspend/SIGUSR1 handler.

Thomas Kho

Copyright 2006 Google (Thomas Kho)
License: LGPL

---

 dlls/ntdll/critsection.c |   28 +++++++++++++++++++++
 dlls/ntdll/loader.c      |   55 +++++++++++++++++++++++++----------------
 dlls/ntdll/ntdll_misc.h  |    7 +++++
 dlls/ntdll/server.c      |   29 ++++++++++++++++++++++
 dlls/ntdll/thread.c      |   28 +++++++++++++++++----
 dlls/ntdll/virtual.c     |   61 +++++++++++++++++++++++++++-------------------
 6 files changed, 155 insertions(+), 53 deletions(-)

diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c
index 581875f..6885141 100644
--- a/dlls/ntdll/critsection.c
+++ b/dlls/ntdll/critsection.c
@@ -37,6 +37,9 @@ #include "ntdll_misc.h"
 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
 WINE_DECLARE_DEBUG_CHANNEL(relay);
 
+extern void wine_unblock_unix_signals(sigset_t *old_set);
+extern void wine_block_unix_signals(sigset_t *old_set);
+
 inline static LONG interlocked_inc( PLONG dest )
 {
     return interlocked_xchg_add( (int *)dest, 1 ) + 1;
@@ -580,3 +583,28 @@ NTSTATUS WINAPI RtlLeaveCriticalSection(
     }
     return STATUS_SUCCESS;
 }
+
+
+/***********************************************************************
+ *           NTDLL_EnterUninterruptedCriticalSection
+ *
+ * NOTE: These functions exist to ensure that threads are not suspended inside
+ * ntdll critical sections and that remote operations succeed.
+ */
+void NTDLL_EnterUninterruptedCriticalSection( RTL_CRITICAL_SECTION *cs,
+                                              sigset_t *sigset )
+{
+    wine_block_suspend_signal(sigset);
+    RtlEnterCriticalSection(cs);
+}
+
+
+/***********************************************************************
+ *           NTDLL_LeaveUninterruptedCriticalSection
+ */
+void NTDLL_LeaveUninterruptedCriticalSection( RTL_CRITICAL_SECTION *cs,
+                                              sigset_t *sigset )
+{
+    RtlLeaveCriticalSection(cs);
+    wine_unblock_suspend_signal(sigset);
+}
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 184f64f..4e6640e 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -964,8 +964,9 @@ static void process_detach( BOOL bForceD
 {
     PLIST_ENTRY mark, entry;
     PLDR_MODULE mod;
+    sigset_t sigset;
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
     if (bForceDetach) process_detaching = 1;
     mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
     do
@@ -991,7 +992,7 @@ static void process_detach( BOOL bForceD
         }
     } while (entry != mark);
 
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
 }
 
 /*************************************************************************
@@ -1006,12 +1007,13 @@ NTSTATUS MODULE_DllThreadAttach( LPVOID 
     PLIST_ENTRY mark, entry;
     PLDR_MODULE mod;
     NTSTATUS    status;
+    sigset_t sigset;
 
     /* don't do any attach calls if process is exiting */
     if (process_detaching) return STATUS_SUCCESS;
     /* FIXME: there is still a race here */
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
 
     if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto done;
 
@@ -1030,7 +1032,7 @@ NTSTATUS MODULE_DllThreadAttach( LPVOID 
     }
 
 done:
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
     return status;
 }
 
@@ -1042,8 +1044,9 @@ NTSTATUS WINAPI LdrDisableThreadCallouts
 {
     WINE_MODREF *wm;
     NTSTATUS    ret = STATUS_SUCCESS;
+    sigset_t sigset;
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
 
     wm = get_modref( hModule );
     if (!wm || wm->ldr.TlsIndex != -1)
@@ -1051,7 +1054,7 @@ NTSTATUS WINAPI LdrDisableThreadCallouts
     else
         wm->ldr.Flags |= LDR_NO_DLL_CALLS;
 
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
 
     return ret;
 }
@@ -1124,6 +1127,7 @@ NTSTATUS WINAPI LdrGetDllHandle(ULONG x,
     UNICODE_STRING str;
     PLIST_ENTRY mark, entry;
     PLDR_MODULE mod;
+    sigset_t sigset;
 
     if (x != 0 || y != 0)
         FIXME("Unknown behavior, please report\n");
@@ -1138,7 +1142,7 @@ NTSTATUS WINAPI LdrGetDllHandle(ULONG x,
         name = &str;
     }
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
 
     if (cached_modref)
     {
@@ -1166,7 +1170,7 @@ NTSTATUS WINAPI LdrGetDllHandle(ULONG x,
         }
     }
 done:
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
     TRACE("%lx %lx %s -> %p\n", x, y, debugstr_us(name), status ? NULL : *base);
     return status;
 }
@@ -1181,8 +1185,9 @@ NTSTATUS WINAPI LdrGetProcedureAddress(H
     IMAGE_EXPORT_DIRECTORY *exports;
     DWORD exp_size;
     NTSTATUS ret = STATUS_PROCEDURE_NOT_FOUND;
+    sigset_t sigset;
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
 
     /* check if the module itself is invalid to return the proper error */
     if (!get_modref( module )) ret = STATUS_DLL_NOT_FOUND;
@@ -1198,7 +1203,7 @@ NTSTATUS WINAPI LdrGetProcedureAddress(H
         }
     }
 
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
     return ret;
 }
 
@@ -1793,8 +1798,9 @@ NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_
 {
     WINE_MODREF *wm;
     NTSTATUS nts;
+    sigset_t sigset;
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
 
     if (!path_name) path_name = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
     nts = load_dll( path_name, libname->Buffer, flags, &wm );
@@ -1810,7 +1816,7 @@ NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_
     }
     *hModule = (wm) ? wm->ldr.BaseAddress : NULL;
 
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
     return nts;
 }
 
@@ -1828,10 +1834,11 @@ NTSTATUS WINAPI LdrQueryProcessModuleInf
     char*               ptr;
     PLIST_ENTRY         mark, entry;
     PLDR_MODULE         mod;
+    sigset_t sigset;
 
     smi->ModulesCount = 0;
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
     mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
     for (entry = mark->Flink; entry != mark; entry = entry->Flink)
     {
@@ -1859,7 +1866,7 @@ NTSTATUS WINAPI LdrQueryProcessModuleInf
         }
         else nts = STATUS_INFO_LENGTH_MISMATCH;
     }
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
 
     if (req_size) *req_size = size;
 
@@ -1884,6 +1891,7 @@ void WINAPI LdrShutdownThread(void)
 {
     PLIST_ENTRY mark, entry;
     PLDR_MODULE mod;
+    sigset_t sigset;
 
     TRACE("()\n");
 
@@ -1891,7 +1899,7 @@ void WINAPI LdrShutdownThread(void)
     if (process_detaching) return;
     /* FIXME: there is still a race here */
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
 
     mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
     for (entry = mark->Blink; entry != mark; entry = entry->Blink)
@@ -1907,7 +1915,7 @@ void WINAPI LdrShutdownThread(void)
                         DLL_THREAD_DETACH, NULL );
     }
 
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
     RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->ThreadLocalStoragePointer );
 }
 
@@ -2016,10 +2024,11 @@ static void MODULE_DecRefCount( WINE_MOD
 NTSTATUS WINAPI LdrUnloadDll( HMODULE hModule )
 {
     NTSTATUS retv = STATUS_SUCCESS;
+    sigset_t sigset;
 
     TRACE("(%p)\n", hModule);
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
 
     /* if we're stopping the whole process (and forcing the removal of all
      * DLLs) the library will be freed anyway
@@ -2051,7 +2060,7 @@ NTSTATUS WINAPI LdrUnloadDll( HMODULE hM
         free_lib_count--;
     }
 
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
 
     return retv;
 }
@@ -2094,6 +2103,7 @@ void WINAPI LdrInitializeThunk( ULONG un
     LPCWSTR load_path;
     PEB *peb = NtCurrentTeb()->Peb;
     IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
+    sigset_t sigset;
 
     if (main_exe_file) NtClose( main_exe_file );  /* at this point the main module is created */
 
@@ -2134,7 +2144,7 @@ void WINAPI LdrInitializeThunk( ULONG un
 
     if (status != STATUS_SUCCESS) goto error;
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
 
     load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
     if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto error;
@@ -2148,7 +2158,7 @@ void WINAPI LdrInitializeThunk( ULONG un
     }
     attach_implicitly_loaded_dlls( (LPVOID)1 );
 
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
 
     if (nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) VIRTUAL_UseLargeAddressSpace();
     return;
@@ -2232,10 +2242,11 @@ PVOID WINAPI RtlPcToFileHeader( PVOID pc
 {
     LDR_MODULE *module;
     PVOID ret = NULL;
+    sigset_t sigset;
 
-    RtlEnterCriticalSection( &loader_section );
+    NTDLL_EnterUninterruptedCriticalSection( &loader_section, &sigset );
     if (!LdrFindEntryForAddress( pc, &module )) ret = module->BaseAddress;
-    RtlLeaveCriticalSection( &loader_section );
+    NTDLL_LeaveUninterruptedCriticalSection( &loader_section, &sigset );
     *address = ret;
     return ret;
 }
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 03110a4..ab01bde 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -107,6 +107,13 @@ extern BOOL DIR_is_hidden_file( const UN
 extern NTSTATUS DIR_unmount_device( HANDLE handle );
 extern NTSTATUS DIR_get_unix_cwd( char **cwd );
 
+/* critical sections */
+extern RTL_CRITICAL_SECTION csThread;
+extern void NTDLL_EnterUninterruptedCriticalSection( RTL_CRITICAL_SECTION *cs,
+                                                     sigset_t *sigset );
+extern void NTDLL_LeaveUninterruptedCriticalSection( RTL_CRITICAL_SECTION *cs,
+                                                     sigset_t *sigset );
+
 /* virtual memory */
 extern NTSTATUS VIRTUAL_HandleFault(LPCVOID addr);
 extern BOOL VIRTUAL_HasMapping( LPCVOID addr );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 97be8ec..702980f 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -455,8 +455,10 @@ #endif
 int wine_server_fd_to_handle( int fd, unsigned int access, unsigned int attributes, obj_handle_t *handle )
 {
     int ret;
+    sigset_t sigset;
 
     *handle = 0;
+    NTDLL_EnterUninterruptedCriticalSection( &csThread, &sigset );
     wine_server_send_fd( fd );
 
     SERVER_START_REQ( alloc_file_handle )
@@ -467,6 +469,7 @@ int wine_server_fd_to_handle( int fd, un
         if (!(ret = wine_server_call( req ))) *handle = reply->handle;
     }
     SERVER_END_REQ;
+    NTDLL_LeaveUninterruptedCriticalSection( &csThread, &sigset );
     return ret;
 }
 
@@ -953,3 +956,29 @@ #endif
                                (version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
     return info_size;
 }
+
+
+/***********************************************************************
+ *           wine_block_suspend_signal
+ */
+void wine_block_suspend_signal(sigset_t *old_set)
+{
+    static sigset_t suspend_set;
+    static unsigned first_time = 1;
+    if (first_time)
+    {
+        first_time = 0;
+        sigemptyset( &suspend_set );
+        sigaddset( &suspend_set, SIGUSR1 );
+    }
+    pthread_functions.sigprocmask( SIG_BLOCK, &suspend_set, old_set );
+}
+
+
+/***********************************************************************
+ *           wine_unblock_suspend_signal
+ */
+void wine_unblock_suspend_signal(sigset_t *old_set)
+{
+    pthread_functions.sigprocmask( SIG_SETMASK, old_set, NULL );
+}
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index dbcc5a6..f732573 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -63,6 +63,15 @@ static ULONG sigstack_zero_bits;
 
 struct wine_pthread_functions pthread_functions = { NULL };
 
+RTL_CRITICAL_SECTION csThread;
+static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
+{
+    0, 0, &csThread,
+    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": csThread") }
+};
+RTL_CRITICAL_SECTION csThread = { &critsect_debug, -1, 0, 0, 0, 0 };
+
 /***********************************************************************
  *           init_teb
  */
@@ -359,7 +368,8 @@ static void start_thread( struct wine_pt
     /* setup the guard page */
     size = page_size;
     NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size, PAGE_NOACCESS, NULL );
-    RtlFreeHeap( GetProcessHeap(), 0, info );
+    size = 0;
+    NtFreeVirtualMemory( NtCurrentProcess(), (PVOID *) &info, &size, MEM_RELEASE );
 
     RtlAcquirePebLock();
     InsertHeadList( &tls_links, &teb->TlsLinks );
@@ -405,6 +415,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
     int request_pipe[2];
     NTSTATUS status;
     SIZE_T size, page_size = getpagesize();
+    sigset_t sigset;
 
     if( ! is_current_process( process ) )
     {
@@ -414,6 +425,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
 
     if (pipe( request_pipe ) == -1) return STATUS_TOO_MANY_OPENED_FILES;
     fcntl( request_pipe[1], F_SETFD, 1 ); /* set close on exec flag */
+    NTDLL_EnterUninterruptedCriticalSection( &csThread, &sigset );
     wine_server_send_fd( request_pipe[0] );
 
     SERVER_START_REQ( new_thread )
@@ -430,14 +442,14 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
         close( request_pipe[0] );
     }
     SERVER_END_REQ;
+    NTDLL_LeaveUninterruptedCriticalSection( &csThread, &sigset );
 
     if (status) goto error;
 
-    if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*info) )))
-    {
-        status = STATUS_NO_MEMORY;
+    size = sizeof(*info);
+    if ((status = NtAllocateVirtualMemory( NtCurrentProcess(), (PVOID *) &info, 0,
+                                           &size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
         goto error;
-    }
 
     addr = NULL;
     size = sigstack_total_size;
@@ -503,7 +515,11 @@ error:
         SIZE_T size = 0;
         NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
     }
-    RtlFreeHeap( GetProcessHeap(), 0, info );
+    if (info)
+    {
+        SIZE_T size = 0;
+        NtFreeVirtualMemory( NtCurrentProcess(), (PVOID *) &info, &size, MEM_RELEASE );
+    }
     if (handle) NtClose( handle );
     close( request_pipe[1] );
     return status;
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index f7b829f..8c6de4a 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -201,15 +201,16 @@ static void VIRTUAL_DumpView( FILE_VIEW 
 #if WINE_VM_DEBUG
 static void VIRTUAL_Dump(void)
 {
+    sigset_t sigset;
     struct file_view *view;
 
     TRACE( "Dump of all virtual memory views:\n" );
-    RtlEnterCriticalSection(&csVirtual);
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
     LIST_FOR_EACH_ENTRY( view, &views_list, FILE_VIEW, entry )
     {
         VIRTUAL_DumpView( view );
     }
-    RtlLeaveCriticalSection(&csVirtual);
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
 }
 #endif
 
@@ -925,13 +926,14 @@ static NTSTATUS map_image( HANDLE hmappi
     NTSTATUS status = STATUS_CONFLICTING_ADDRESSES;
     int i;
     off_t pos;
+    sigset_t sigset;
     struct stat st;
     struct file_view *view = NULL;
     char *ptr, *header_end;
 
     /* zero-map the whole range */
 
-    RtlEnterCriticalSection( &csVirtual );
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
 
     if (base >= (char *)0x110000)  /* make sure the DOS area remains free */
         status = map_view( &view, base, total_size, mask, FALSE,
@@ -1176,14 +1178,14 @@ static NTSTATUS map_image( HANDLE hmappi
                            NtCurrentProcess(), &view->mapping,
                            0, 0, DUPLICATE_SAME_ACCESS );
 
-    RtlLeaveCriticalSection( &csVirtual );
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
 
     *addr_ptr = ptr;
     return STATUS_SUCCESS;
 
  error:
     if (view) delete_view( view );
-    RtlLeaveCriticalSection( &csVirtual );
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
     return status;
 }
 
@@ -1251,8 +1253,9 @@ NTSTATUS VIRTUAL_HandleFault( LPCVOID ad
 {
     FILE_VIEW *view;
     NTSTATUS ret = STATUS_ACCESS_VIOLATION;
+    sigset_t sigset;
 
-    RtlEnterCriticalSection( &csVirtual );
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
     if ((view = VIRTUAL_FindView( addr )))
     {
         void *page = ROUND_ADDR( addr, page_mask );
@@ -1263,7 +1266,7 @@ NTSTATUS VIRTUAL_HandleFault( LPCVOID ad
             ret = STATUS_GUARD_PAGE_VIOLATION;
         }
     }
-    RtlLeaveCriticalSection( &csVirtual );
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
     return ret;
 }
 
@@ -1276,10 +1279,11 @@ BOOL VIRTUAL_HasMapping( LPCVOID addr )
 {
     FILE_VIEW *view;
     BOOL ret = FALSE;
+    sigset_t sigset;
 
-    RtlEnterCriticalSection( &csVirtual );
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
     if ((view = VIRTUAL_FindView( addr ))) ret = (view->mapping != 0);
-    RtlLeaveCriticalSection( &csVirtual );
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
     return ret;
 }
 
@@ -1309,6 +1313,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory(
     SIZE_T size = *size_ptr;
     SIZE_T mask = get_mask( zero_bits );
     NTSTATUS status = STATUS_SUCCESS;
+    sigset_t sigset;
     struct file_view *view;
 
     TRACE("%p %p %08lx %lx %08lx\n", process, *ret, size, type, protect );
@@ -1361,7 +1366,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory(
 
     /* Reserve the memory */
 
-    if (use_locks) RtlEnterCriticalSection( &csVirtual );
+    if (use_locks) NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
 
     if (type & MEM_SYSTEM)
     {
@@ -1389,7 +1394,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory(
         else if (!VIRTUAL_SetProt( view, base, size, vprot )) status = STATUS_ACCESS_DENIED;
     }
 
-    if (use_locks) RtlLeaveCriticalSection( &csVirtual );
+    if (use_locks) NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
 
     if (status == STATUS_SUCCESS)
     {
@@ -1411,6 +1416,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HAN
     NTSTATUS status = STATUS_SUCCESS;
     LPVOID addr = *addr_ptr;
     SIZE_T size = *size_ptr;
+    sigset_t sigset;
 
     TRACE("%p %p %08lx %lx\n", process, addr, size, type );
 
@@ -1425,7 +1431,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HAN
     size = ROUND_SIZE( addr, size );
     base = ROUND_ADDR( addr, page_mask );
 
-    RtlEnterCriticalSection(&csVirtual);
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
 
     if (!(view = VIRTUAL_FindView( base )) ||
         (base + size > (char *)view->base + view->size) ||
@@ -1469,7 +1475,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HAN
         status = STATUS_INVALID_PARAMETER;
     }
 
-    RtlLeaveCriticalSection(&csVirtual);
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
     return status;
 }
 
@@ -1489,6 +1495,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory( 
     ULONG prot;
     SIZE_T size = *size_ptr;
     LPVOID addr = *addr_ptr;
+    sigset_t sigset;
 
     TRACE("%p %p %08lx %08lx\n", process, addr, size, new_prot );
 
@@ -1503,7 +1510,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory( 
     size = ROUND_SIZE( addr, size );
     base = ROUND_ADDR( addr, page_mask );
 
-    RtlEnterCriticalSection( &csVirtual );
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
 
     if (!(view = VIRTUAL_FindView( base )) || (base + size > (char *)view->base + view->size))
     {
@@ -1530,7 +1537,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory( 
             if (!VIRTUAL_SetProt( view, base, size, vprot )) status = STATUS_ACCESS_DENIED;
         }
     }
-    RtlLeaveCriticalSection( &csVirtual );
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
 
     if (status == STATUS_SUCCESS)
     {
@@ -1558,6 +1565,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
     struct list *ptr;
     SIZE_T size = 0;
     MEMORY_BASIC_INFORMATION *info = buffer;
+    sigset_t sigset;
 
     if (info_class != MemoryBasicInformation)
     {
@@ -1586,7 +1594,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
 
     /* Find the view containing the address */
 
-    RtlEnterCriticalSection(&csVirtual);
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
     ptr = list_head( &views_list );
     for (;;)
     {
@@ -1598,7 +1606,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
             {
                 if (user_space_limit && base >= (char *)user_space_limit)
                 {
-                    RtlLeaveCriticalSection( &csVirtual );
+                    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
                     return STATUS_WORKING_SET_LIMIT_RANGE;
                 }
                 size = (char *)user_space_limit - alloc_base;
@@ -1645,7 +1653,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
         for (size = base - alloc_base; size < view->size; size += page_size)
             if (view->prot[size >> page_shift] != vprot) break;
     }
-    RtlLeaveCriticalSection(&csVirtual);
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
 
     info->BaseAddress    = (LPVOID)base;
     info->AllocationBase = (LPVOID)alloc_base;
@@ -1774,6 +1782,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
     HANDLE shared_file;
     BOOL removable = FALSE;
     LARGE_INTEGER offset;
+    sigset_t sigset;
 
     offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0;
 
@@ -1881,12 +1890,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
 
     /* Reserve a properly aligned area */
 
-    RtlEnterCriticalSection( &csVirtual );
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
 
     res = map_view( &view, *addr_ptr, size, mask, FALSE, prot );
     if (res)
     {
-        RtlLeaveCriticalSection( &csVirtual );
+        NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
         goto done;
     }
 
@@ -1913,7 +1922,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
         delete_view( view );
     }
 
-    RtlLeaveCriticalSection( &csVirtual );
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
 
 done:
     wine_server_release_fd( handle, unix_handle );
@@ -1929,6 +1938,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HA
 {
     FILE_VIEW *view;
     NTSTATUS status = STATUS_INVALID_PARAMETER;
+    sigset_t sigset;
     void *base = ROUND_ADDR( addr, page_mask );
 
     if (!is_current_process( process ))
@@ -1936,13 +1946,13 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HA
         ERR("Unsupported on other process\n");
         return STATUS_ACCESS_DENIED;
     }
-    RtlEnterCriticalSection( &csVirtual );
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
     if ((view = VIRTUAL_FindView( base )) && (base == view->base))
     {
         delete_view( view );
         status = STATUS_SUCCESS;
     }
-    RtlLeaveCriticalSection( &csVirtual );
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
     return status;
 }
 
@@ -1956,6 +1966,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HA
 {
     FILE_VIEW *view;
     NTSTATUS status = STATUS_SUCCESS;
+    sigset_t sigset;
     void *addr = ROUND_ADDR( *addr_ptr, page_mask );
 
     if (!is_current_process( process ))
@@ -1963,7 +1974,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HA
         ERR("Unsupported on other process\n");
         return STATUS_ACCESS_DENIED;
     }
-    RtlEnterCriticalSection( &csVirtual );
+    NTDLL_EnterUninterruptedCriticalSection( &csVirtual, &sigset );
     if (!(view = VIRTUAL_FindView( addr ))) status = STATUS_INVALID_PARAMETER;
     else
     {
@@ -1971,7 +1982,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HA
         *addr_ptr = addr;
         if (msync( addr, *size_ptr, MS_SYNC )) status = STATUS_NOT_MAPPED_DATA;
     }
-    RtlLeaveCriticalSection( &csVirtual );
+    NTDLL_LeaveUninterruptedCriticalSection( &csVirtual, &sigset );
     return status;
 }
 



More information about the wine-patches mailing list