From b5303c046f138b62b4bb299164faade8dbb56ff0 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 14 Feb 2012 00:57:32 +0000 Subject: [PATCH] [CSRSRV2/CSRSS2]: Make multiple fixes to, bring up to speed, and finish implementation of the CSRSS/CSRSRV that has been laying around in trunk since forever. Not yet tested if it actually works yet, but it should now build and be much closer to fully functional. Of course, the trick is to figure out how to get it to co-exist with the current CSRSS/win32csr. svn path=/trunk/; revision=55585 --- reactos/include/reactos/subsys/csr/server.h | 80 +- reactos/subsystems/CMakeLists.txt | 1 + reactos/subsystems/csr/CMakeLists.txt | 16 + reactos/subsystems/csr/csr.rbuild | 15 - reactos/subsystems/csr/csrsrv/CMakeLists.txt | 30 + reactos/subsystems/csr/csrsrv/api.c | 666 +++++++++----- reactos/subsystems/csr/csrsrv/csrsrv.rbuild | 18 - .../csr/csrsrv/{csrsrv.spec => csrsrv2.spec} | 2 +- reactos/subsystems/csr/csrsrv/init.c | 839 ++++++------------ reactos/subsystems/csr/csrsrv/process.c | 418 +++++---- reactos/subsystems/csr/csrsrv/server.c | 61 +- reactos/subsystems/csr/csrsrv/session.c | 130 ++- reactos/subsystems/csr/csrsrv/srv.h | 42 +- reactos/subsystems/csr/csrsrv/status.h | 4 +- reactos/subsystems/csr/csrsrv/thread.c | 215 +++-- reactos/subsystems/csr/csrsrv/wait.c | 34 +- reactos/subsystems/csr/main.c | 19 - 17 files changed, 1383 insertions(+), 1207 deletions(-) create mode 100644 reactos/subsystems/csr/CMakeLists.txt delete mode 100644 reactos/subsystems/csr/csr.rbuild create mode 100644 reactos/subsystems/csr/csrsrv/CMakeLists.txt delete mode 100644 reactos/subsystems/csr/csrsrv/csrsrv.rbuild rename reactos/subsystems/csr/csrsrv/{csrsrv.spec => csrsrv2.spec} (96%) diff --git a/reactos/include/reactos/subsys/csr/server.h b/reactos/include/reactos/subsys/csr/server.h index ca63a6ddb6e..db3a506e657 100644 --- a/reactos/include/reactos/subsys/csr/server.h +++ b/reactos/include/reactos/subsys/csr/server.h @@ -18,7 +18,7 @@ typedef struct _CSR_NT_SESSION { ULONG ReferenceCount; - LIST_ENTRY SessionList; + LIST_ENTRY SessionLink; ULONG SessionId; } CSR_NT_SESSION, *PCSR_NT_SESSION; @@ -71,12 +71,21 @@ typedef enum _CSR_PROCESS_FLAGS { CsrProcessTerminating = 0x1, CsrProcessSkipShutdown = 0x2, + CsrProcessNormalPriority = 0x10, + CsrProcessIdlePriority = 0x20, + CsrProcessHighPriority = 0x40, + CsrProcessRealtimePriority = 0x80, CsrProcessCreateNewGroup = 0x100, CsrProcessTerminated = 0x200, CsrProcessLastThreadTerminated = 0x400, CsrProcessIsConsoleApp = 0x800 } CSR_PROCESS_FLAGS, *PCSR_PROCESS_FLAGS; +#define CsrProcessPriorityFlags (CsrProcessNormalPriority | \ + CsrProcessIdlePriority | \ + CsrProcessHighPriority | \ + CsrProcessRealtimePriority) + typedef enum _CSR_THREAD_FLAGS { CsrThreadAltertable = 0x1, @@ -252,75 +261,6 @@ typedef struct _CSR_WAIT_BLOCK CSR_API_MESSAGE WaitApiMessage; } CSR_WAIT_BLOCK, *PCSR_WAIT_BLOCK; -/* FIXME: Put into new SM headers */ -typedef struct _SB_CREATE_SESSION -{ - ULONG SessionId; - RTL_USER_PROCESS_INFORMATION ProcessInfo; -} SB_CREATE_SESSION, *PSB_CREATE_SESSION; - -typedef struct _SB_TERMINATE_SESSION -{ - ULONG SessionId; -} SB_TERMINATE_SESSION, *PSB_TERMINATE_SESSION; - -typedef struct _SB_FOREIGN_SESSION_COMPLETE -{ - ULONG SessionId; -} SB_FOREIGN_SESSION_COMPLETE, *PSB_FOREIGN_SESSION_COMPLETE; - -typedef struct _SB_CREATE_PROCESS -{ - ULONG SessionId; -} SB_CREATE_PROCESS, *PSB_CREATE_PROCESS; - -typedef struct _SB_CONNECTION_INFO -{ - ULONG SubsystemId; -} SB_CONNECTION_INFO, *PSB_CONNECTION_INFO; - -typedef struct _SB_API_MESSAGE -{ - PORT_MESSAGE Header; - union - { - SB_CONNECTION_INFO ConnectionInfo; - struct - { - ULONG Opcode; - NTSTATUS Status; - union - { - SB_CREATE_SESSION SbCreateSession; - SB_TERMINATE_SESSION SbTerminateSession; - SB_FOREIGN_SESSION_COMPLETE SbForeignSessionComplete; - SB_CREATE_PROCESS SbCreateProcess; - }; - }; - }; -} SB_API_MESSAGE, *PSB_API_MESSAGE; - -typedef -BOOLEAN -(NTAPI *PSB_API_ROUTINE)(IN PSB_API_MESSAGE ApiMessage); - -NTSTATUS -NTAPI -SmSessionComplete( - IN HANDLE hApiPort, - IN ULONG SessionId, - IN NTSTATUS Status -); - -NTSTATUS -NTAPI -SmConnectToSm( - IN PUNICODE_STRING SbApiPortName OPTIONAL, - IN HANDLE hSbApiPort OPTIONAL, - IN ULONG SubsystemType OPTIONAL, - OUT PHANDLE hSmApiPort -); - /* PROTOTYPES ****************************************************************/ NTSTATUS diff --git a/reactos/subsystems/CMakeLists.txt b/reactos/subsystems/CMakeLists.txt index 86b3cd1727b..9ae37a8221c 100644 --- a/reactos/subsystems/CMakeLists.txt +++ b/reactos/subsystems/CMakeLists.txt @@ -1,4 +1,5 @@ if(ARCH MATCHES i386) add_subdirectory(ntvdm) endif() +add_subdirectory(csr) add_subdirectory(win32) diff --git a/reactos/subsystems/csr/CMakeLists.txt b/reactos/subsystems/csr/CMakeLists.txt new file mode 100644 index 00000000000..29ccac1a8da --- /dev/null +++ b/reactos/subsystems/csr/CMakeLists.txt @@ -0,0 +1,16 @@ + +include_directories( + include + ${REACTOS_SOURCE_DIR}/include/reactos/subsys + ${REACTOS_SOURCE_DIR}/include/reactos/drivers) + +add_executable(csrss2 main.c csr.rc) + +set_module_type(csrss2 nativecui) +target_link_libraries(csrss2 nt) +add_importlibs(csrss2 ntdll csrsrv2) +add_dependencies(csrss2 psdk bugcodes) +add_cd_file(TARGET csrss2 DESTINATION reactos/system32 FOR all) + +add_subdirectory(csrsrv) + diff --git a/reactos/subsystems/csr/csr.rbuild b/reactos/subsystems/csr/csr.rbuild deleted file mode 100644 index aec8f30fbab..00000000000 --- a/reactos/subsystems/csr/csr.rbuild +++ /dev/null @@ -1,15 +0,0 @@ - - - - - . - include/reactos/subsys - nt - ntdll - csrsrv - main.c - - - - - diff --git a/reactos/subsystems/csr/csrsrv/CMakeLists.txt b/reactos/subsystems/csr/csrsrv/CMakeLists.txt new file mode 100644 index 00000000000..24ffd89a58e --- /dev/null +++ b/reactos/subsystems/csr/csrsrv/CMakeLists.txt @@ -0,0 +1,30 @@ + +include_directories(${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include) +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/subsys) + +spec2def(csrsrv2.dll csrsrv2.spec) + +list(APPEND SOURCE + api.c + init.c + process.c + server.c + session.c + thread.c + wait.c + csrsrv.rc + ${CMAKE_CURRENT_BINARY_DIR}/csrsrv2.def) + +add_library(csrsrv2 SHARED ${SOURCE}) + +target_link_libraries(csrsrv2 ${PSEH_LIB} smlib) + +set_module_type(csrsrv2 nativedll) + +add_importlibs(csrsrv2 ntdll) + +add_pch(csrsrv2 srv.h) + +add_dependencies(csrsrv2 psdk bugcodes) +add_cd_file(TARGET csrsrv2 DESTINATION reactos/system32 FOR all) +add_importlib_target(csrsrv2.spec) diff --git a/reactos/subsystems/csr/csrsrv/api.c b/reactos/subsystems/csr/csrsrv/api.c index 123e6ff0486..75c19d47afd 100644 --- a/reactos/subsystems/csr/csrsrv/api.c +++ b/reactos/subsystems/csr/csrsrv/api.c @@ -21,15 +21,15 @@ UNICODE_STRING CsrApiPortName; HANDLE CsrSbApiPort; HANDLE CsrApiPort; PCSR_THREAD CsrSbApiRequestThreadPtr; -ULONG CsrpStaticThreadCount; -ULONG CsrpDynamicThreadTotal; +volatile LONG CsrpStaticThreadCount; +volatile LONG CsrpDynamicThreadTotal; /* PRIVATE FUNCTIONS *********************************************************/ /*++ - * @name CsrCheckRequestThreads + * @name CsrpCheckRequestThreads * - * The CsrCheckRequestThreads routine checks if there are no more threads + * The CsrpCheckRequestThreads routine checks if there are no more threads * to handle CSR API Requests, and creates a new thread if possible, to * avoid starvation. * @@ -43,14 +43,14 @@ ULONG CsrpDynamicThreadTotal; *--*/ NTSTATUS NTAPI -CsrCheckRequestThreads(VOID) +CsrpCheckRequestThreads(VOID) { HANDLE hThread; CLIENT_ID ClientId; NTSTATUS Status; /* Decrease the count, and see if we're out */ - if (!(_InterlockedDecrement((PLONG)&CsrpStaticThreadCount))) + if (!(_InterlockedDecrement(&CsrpStaticThreadCount))) { /* Check if we've still got space for a Dynamic Thread */ if (CsrpDynamicThreadTotal < CsrMaxApiRequestThreads) @@ -67,11 +67,11 @@ CsrCheckRequestThreads(VOID) &hThread, &ClientId); /* Check success */ - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Increase the thread counts */ - CsrpStaticThreadCount++; - CsrpDynamicThreadTotal++; + _InterlockedIncrement(&CsrpStaticThreadCount); + _InterlockedIncrement(&CsrpDynamicThreadTotal); /* Add a new server thread */ if (CsrAddStaticServerThread(hThread, @@ -84,8 +84,8 @@ CsrCheckRequestThreads(VOID) else { /* Failed to create a new static thread */ - CsrpStaticThreadCount--; - CsrpDynamicThreadTotal--; + _InterlockedDecrement(&CsrpStaticThreadCount); + _InterlockedDecrement(&CsrpDynamicThreadTotal); /* Terminate it */ NtTerminateThread(hThread,0); @@ -131,16 +131,23 @@ CsrSbApiPortInitialize(VOID) /* Calculate how much space we'll need for the Port Name */ Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR); - /* Allocate space for it, and create it */ + /* Create the buffer for it */ CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size); + if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY; + + /* Setup the rest of the empty string */ CsrSbApiPortName.Length = 0; CsrSbApiPortName.MaximumLength = (USHORT)Size; + + /* Now append the full port name */ RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName); RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP); RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME); + if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName); /* Create Security Descriptor for this Port */ - CsrCreateLocalSystemSD(&PortSd); + Status = CsrCreateLocalSystemSD(&PortSd); + if (!NT_SUCCESS(Status)) return Status; /* Initialize the Attributes */ InitializeObjectAttributes(&ObjectAttributes, @@ -153,36 +160,36 @@ CsrSbApiPortInitialize(VOID) Status = NtCreatePort(&CsrSbApiPort, &ObjectAttributes, sizeof(SB_CONNECTION_INFO), - sizeof(SB_API_MESSAGE), - 32 * sizeof(SB_API_MESSAGE)); - if(!NT_SUCCESS(Status)) - { + sizeof(PSB_API_MSG), + 32 * sizeof(PSB_API_MSG)); + if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd); + if (NT_SUCCESS(Status)) + { + /* Create the Thread to handle the API Requests */ + Status = RtlCreateUserThread(NtCurrentProcess(), + NULL, + TRUE, + 0, + 0, + 0, + (PVOID)CsrSbApiRequestThread, + NULL, + &hRequestThread, + &ClientId); + if (NT_SUCCESS(Status)) + { + /* Add it as a Static Server Thread */ + CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread, + &ClientId, + 0); + + /* Activate it */ + Status = NtResumeThread(hRequestThread, NULL); + } } - /* Create the Thread to handle the API Requests */ - Status = RtlCreateUserThread(NtCurrentProcess(), - NULL, - TRUE, - 0, - 0, - 0, - (PVOID)CsrSbApiRequestThread, - NULL, - &hRequestThread, - &ClientId); - if(!NT_SUCCESS(Status)) - { - - } - - /* Add it as a Static Server Thread */ - CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread, - &ClientId, - 0); - - /* Activate it */ - return NtResumeThread(hRequestThread, NULL); + return Status; } /*++ @@ -215,13 +222,22 @@ CsrApiPortInitialize(VOID) /* Calculate how much space we'll need for the Port Name */ Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR); - /* Allocate space for it, and create it */ + /* Create the buffer for it */ CsrApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size); + if (!CsrApiPortName.Buffer) return STATUS_NO_MEMORY; + + /* Setup the rest of the empty string */ CsrApiPortName.Length = 0; CsrApiPortName.MaximumLength = (USHORT)Size; RtlAppendUnicodeStringToString(&CsrApiPortName, &CsrDirectoryName); RtlAppendUnicodeToString(&CsrApiPortName, UNICODE_PATH_SEP); RtlAppendUnicodeToString(&CsrApiPortName, CSR_PORT_NAME); + if (CsrDebug & 1) + { + DPRINT1("CSRSS: Creating %wZ port and associated threads\n", &CsrApiPortName); + DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld sizeof( API_MSG ) == %ld\n", + sizeof(CSR_CONNECTION_INFO), sizeof(CSR_API_MESSAGE)); + } /* FIXME: Create a Security Descriptor */ @@ -238,68 +254,63 @@ CsrApiPortInitialize(VOID) sizeof(CSR_CONNECTION_INFO), sizeof(CSR_API_MESSAGE), 16 * PAGE_SIZE); - if(!NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { - - } - - /* Create the event the Port Thread will use */ - Status = NtCreateEvent(&hRequestEvent, - EVENT_ALL_ACCESS, - NULL, - SynchronizationEvent, - FALSE); - if(!NT_SUCCESS(Status)) - { - - } - - /* Create the Request Thread */ - Status = RtlCreateUserThread(NtCurrentProcess(), - NULL, - TRUE, - 0, - 0, - 0, - (PVOID)CsrApiRequestThread, - (PVOID)hRequestEvent, - &hThread, - &ClientId); - if(!NT_SUCCESS(Status)) - { - - } - - /* Add this as a static thread to CSRSRV */ - CsrAddStaticServerThread(hThread, &ClientId, CsrThreadIsServerThread); - - /* Get the Thread List Pointers */ - ListHead = &CsrRootProcess->ThreadList; - NextEntry = ListHead->Flink; - - /* Start looping the list */ - while (NextEntry != ListHead) - { - /* Get the Thread */ - ServerThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); - - /* Start it up */ - Status = NtResumeThread(ServerThread->ThreadHandle, NULL); - - /* Is this a Server Thread? */ - if (ServerThread->Flags & CsrThreadIsServerThread) + /* Create the event the Port Thread will use */ + Status = NtCreateEvent(&hRequestEvent, + EVENT_ALL_ACCESS, + NULL, + SynchronizationEvent, + FALSE); + if (NT_SUCCESS(Status)) { - /* If so, then wait for it to initialize */ - NtWaitForSingleObject(hRequestEvent, FALSE, NULL); + /* Create the Request Thread */ + Status = RtlCreateUserThread(NtCurrentProcess(), + NULL, + TRUE, + 0, + 0, + 0, + (PVOID)CsrApiRequestThread, + (PVOID)hRequestEvent, + &hThread, + &ClientId); + if (NT_SUCCESS(Status)) + { + /* Add this as a static thread to CSRSRV */ + CsrAddStaticServerThread(hThread, &ClientId, CsrThreadIsServerThread); + + /* Get the Thread List Pointers */ + ListHead = &CsrRootProcess->ThreadList; + NextEntry = ListHead->Flink; + + /* Start looping the list */ + while (NextEntry != ListHead) + { + /* Get the Thread */ + ServerThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); + + /* Start it up */ + Status = NtResumeThread(ServerThread->ThreadHandle, NULL); + + /* Is this a Server Thread? */ + if (ServerThread->Flags & CsrThreadIsServerThread) + { + /* If so, then wait for it to initialize */ + Status = NtWaitForSingleObject(hRequestEvent, FALSE, NULL); + ASSERT(NT_SUCCESS(Status)); + } + + /* Next thread */ + NextEntry = NextEntry->Flink; + } + + /* We don't need this anymore */ + NtClose(hRequestEvent); + } } - - /* Next thread */ - NextEntry = NextEntry->Flink; } - /* We don't need this anymore */ - NtClose(hRequestEvent); - /* Return */ return Status; } @@ -325,32 +336,29 @@ CsrApiRequestThread(IN PVOID Parameter) { PTEB Teb = NtCurrentTeb(); LARGE_INTEGER TimeOut; - PCSR_THREAD CurrentThread; + PCSR_THREAD CurrentThread, CsrThread; NTSTATUS Status; - PCSR_API_MESSAGE ReplyMsg = NULL; + PCSR_API_MESSAGE ReplyMsg; CSR_API_MESSAGE ReceiveMsg; - PCSR_THREAD CsrThread; PCSR_PROCESS CsrProcess; PHARDERROR_MSG HardErrorMsg; PVOID PortContext; - ULONG MessageType; - ULONG i; PCSR_SERVER_DLL ServerDll; PCLIENT_DIED_MSG ClientDiedMsg; PDBGKM_MSG DebugMessage; - ULONG ServerId, ApiId; - ULONG Reply; + ULONG ServerId, ApiId, Reply, MessageType, i; + HANDLE ReplyPort; - /* Probably because of the way GDI is loaded, this has to be done here */ - Teb->GdiClientPID = HandleToUlong(Teb->ClientId.UniqueProcess); - Teb->GdiClientTID = HandleToUlong(Teb->ClientId.UniqueThread); - - /* Set up the timeout for the connect (30 seconds) */ - TimeOut.QuadPart = -30 * 1000 * 1000 * 10; + /* Setup LPC loop port and message */ + ReplyMsg = NULL; + ReplyPort = CsrApiPort; /* Connect to user32 */ while (!CsrConnectToUser()) { + /* Set up the timeout for the connect (30 seconds) */ + TimeOut.QuadPart = -30 * 1000 * 1000 * 10; + /* Keep trying until we get a response */ Teb->Win32ClientInfo[0] = 0; NtDelayExecution(FALSE, &TimeOut); @@ -363,11 +371,12 @@ CsrApiRequestThread(IN PVOID Parameter) if (Parameter) { /* Set it, to let stuff waiting on us load */ - NtSetEvent((HANDLE)Parameter, NULL); + Status = NtSetEvent((HANDLE)Parameter, NULL); + ASSERT(NT_SUCCESS(Status)); /* Increase the Thread Counts */ - _InterlockedIncrement((PLONG)&CsrpStaticThreadCount); - _InterlockedIncrement((PLONG)&CsrpDynamicThreadTotal); + _InterlockedIncrement(&CsrpStaticThreadCount); + _InterlockedIncrement(&CsrpDynamicThreadTotal); } /* Now start the loop */ @@ -376,21 +385,49 @@ CsrApiRequestThread(IN PVOID Parameter) /* Make sure the real CID is set */ Teb->RealClientId = Teb->ClientId; + /* Debug check */ + if (Teb->CountOfOwnedCriticalSections) + { + DPRINT1("CSRSRV: FATAL ERROR. CsrThread is Idle while holding %lu critical sections\n", + Teb->CountOfOwnedCriticalSections); + DPRINT1("CSRSRV: Last Receive Message %lx ReplyMessage %lx\n", + &ReceiveMsg, ReplyMsg); + DbgBreakPoint(); + } + /* Wait for a message to come through */ - Status = NtReplyWaitReceivePort(CsrApiPort, + Status = NtReplyWaitReceivePort(ReplyPort, &PortContext, - (PPORT_MESSAGE)ReplyMsg, - (PPORT_MESSAGE)&ReceiveMsg); + &ReplyMsg->Header, + &ReceiveMsg.Header); /* Check if we didn't get success */ - if(Status != STATUS_SUCCESS) + if (Status != STATUS_SUCCESS) { - /* If we only got a warning, keep going */ - if (NT_SUCCESS(Status)) continue; + /* Was it a failure or another success code? */ + if (!NT_SUCCESS(Status)) + { + /* Check for specific status cases */ + if ((Status != STATUS_INVALID_CID) && + (Status != STATUS_UNSUCCESSFUL) && + ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort))) + { + /* Notify the debugger */ + DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status); + DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n", ReplyPort, CsrApiPort); + } - /* We failed big time, so start out fresh */ - ReplyMsg = NULL; - continue; + /* We failed big time, so start out fresh */ + ReplyMsg = NULL; + ReplyPort = CsrApiPort; + continue; + } + else + { + /* A bizare "success" code, just try again */ + DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status); + continue; + } } /* Use whatever Client ID we got */ @@ -404,6 +441,7 @@ CsrApiRequestThread(IN PVOID Parameter) { /* Handle the Connection Request */ CsrApiHandleConnectionRequest(&ReceiveMsg); + ReplyPort = CsrApiPort; ReplyMsg = NULL; continue; } @@ -416,7 +454,7 @@ CsrApiRequestThread(IN PVOID Parameter) &ReceiveMsg.Header.ClientId); /* Did we find a thread? */ - if(!CsrThread) + if (!CsrThread) { /* This wasn't a CSR Thread, release lock */ CsrReleaseProcessLock(); @@ -425,6 +463,7 @@ CsrApiRequestThread(IN PVOID Parameter) if (MessageType == LPC_EXCEPTION) { ReplyMsg = &ReceiveMsg; + ReplyPort = CsrApiPort; ReplyMsg->Status = DBG_CONTINUE; } else if (MessageType == LPC_PORT_CLOSED || @@ -432,6 +471,7 @@ CsrApiRequestThread(IN PVOID Parameter) { /* The Client or Port are gone, loop again */ ReplyMsg = NULL; + ReplyPort = CsrApiPort; } else if (MessageType == LPC_ERROR_EVENT) { @@ -442,7 +482,7 @@ CsrApiRequestThread(IN PVOID Parameter) HardErrorMsg->Response = ResponseNotHandled; /* Check if there are free api threads */ - CsrCheckRequestThreads(); + CsrpCheckRequestThreads(); if (CsrpStaticThreadCount) { /* Loop every Server DLL */ @@ -452,10 +492,10 @@ CsrApiRequestThread(IN PVOID Parameter) ServerDll = CsrLoadedServerDll[i]; /* Check if it's valid and if it has a Hard Error Callback */ - if (ServerDll && ServerDll->HardErrorCallback) + if ((ServerDll) && (ServerDll->HardErrorCallback)) { /* Call it */ - (*ServerDll->HardErrorCallback)(CsrThread, HardErrorMsg); + ServerDll->HardErrorCallback(NULL, HardErrorMsg); /* If it's handled, get out of here */ if (HardErrorMsg->Response != ResponseNotHandled) break; @@ -464,12 +504,13 @@ CsrApiRequestThread(IN PVOID Parameter) } /* Increase the thread count */ - _InterlockedIncrement((PLONG)&CsrpStaticThreadCount); + _InterlockedIncrement(&CsrpStaticThreadCount); /* If the response was 0xFFFFFFFF, we'll ignore it */ if (HardErrorMsg->Response == 0xFFFFFFFF) { ReplyMsg = NULL; + ReplyPort = CsrApiPort; } else { @@ -480,6 +521,7 @@ CsrApiRequestThread(IN PVOID Parameter) { /* This is an API Message coming from a non-CSR Thread */ ReplyMsg = &ReceiveMsg; + ReplyPort = CsrApiPort; ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION; } else if (MessageType == LPC_DATAGRAM) @@ -488,54 +530,76 @@ CsrApiRequestThread(IN PVOID Parameter) ServerId = CSR_SERVER_ID_FROM_OPCODE(ReceiveMsg.Opcode); /* Make sure that the ID is within limits, and the Server DLL loaded */ + ServerDll = NULL; if ((ServerId >= CSR_SERVER_DLL_MAX) || (!(ServerDll = CsrLoadedServerDll[ServerId]))) { /* We are beyond the Maximum Server ID */ + DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", + ServerId, ServerDll); + DbgBreakPoint(); + ReplyPort = CsrApiPort; ReplyMsg = NULL; + continue; } - else + + /* Get the API ID */ + ApiId = CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode); + + /* Normalize it with our Base ID */ + ApiId -= ServerDll->ApiBase; + + /* Make sure that the ID is within limits, and the entry exists */ + if (ApiId >= ServerDll->HighestApiSupported) { - /* Get the API ID */ - ApiId = CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode); - - /* Normalize it with our Base ID */ - ApiId -= ServerDll->ApiBase; - - /* Make sure that the ID is within limits, and the entry exists */ - if ((ApiId >= ServerDll->HighestApiSupported)) - { - /* We are beyond the Maximum API ID, or it doesn't exist */ - ReplyMsg = NULL; - } - - /* Assume success */ - ReceiveMsg.Status = STATUS_SUCCESS; - - /* Validation complete, start SEH */ - _SEH2_TRY - { - /* Make sure we have enough threads */ - CsrCheckRequestThreads(); - - /* Call the API and get the result */ - ReplyMsg = NULL; - (ServerDll->DispatchTable[ApiId])(&ReceiveMsg, &Reply); - - /* Increase the static thread count */ - _InterlockedIncrement((PLONG)&CsrpStaticThreadCount); - } - _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation())) - { - ReplyMsg = NULL; - } - _SEH2_END; + /* We are beyond the Maximum API ID, or it doesn't exist */ + DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n", + CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode), + &ServerDll->Name); + ReplyPort = CsrApiPort; + ReplyMsg = NULL; + continue; } + + if (CsrDebug & 2) + { + DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n", + Teb->ClientId.UniqueThread, + ReceiveMsg.Header.ClientId.UniqueProcess, + ReceiveMsg.Header.ClientId.UniqueThread, + ServerDll->NameTable[ApiId], + NULL); + } + + /* Assume success */ + ReceiveMsg.Status = STATUS_SUCCESS; + + /* Validation complete, start SEH */ + _SEH2_TRY + { + /* Make sure we have enough threads */ + CsrpCheckRequestThreads(); + + /* Call the API and get the result */ + ReplyMsg = NULL; + ReplyPort = CsrApiPort; + ServerDll->DispatchTable[ApiId](&ReceiveMsg, &Reply); + + /* Increase the static thread count */ + _InterlockedIncrement(&CsrpStaticThreadCount); + } + _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation())) + { + ReplyMsg = NULL; + ReplyPort = CsrApiPort; + } + _SEH2_END; } else { /* Some other ignored message type */ ReplyMsg = NULL; + ReplyPort = CsrApiPort; } /* Keep going */ @@ -553,7 +617,7 @@ CsrApiRequestThread(IN PVOID Parameter) if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart) { /* Reference the thread */ - CsrThread->ReferenceCount++; + CsrLockedReferenceThread(CsrThread); /* Destroy the thread in the API Message */ CsrDestroyThread(&ReceiveMsg.Header.ClientId); @@ -572,11 +636,12 @@ CsrApiRequestThread(IN PVOID Parameter) /* Release the lock and keep looping */ CsrReleaseProcessLock(); ReplyMsg = NULL; + ReplyPort = CsrApiPort; continue; } /* Reference the thread and release the lock */ - CsrThread->ReferenceCount++; + CsrLockedReferenceThread(CsrThread); CsrReleaseProcessLock(); /* Check if this was an exception */ @@ -592,6 +657,7 @@ CsrApiRequestThread(IN PVOID Parameter) DebugMessage = (PDBGKM_MSG)&ReceiveMsg; DebugMessage->ReturnedStatus = DBG_CONTINUE; ReplyMsg = &ReceiveMsg; + ReplyPort = CsrApiPort; /* Remove our extra reference */ CsrDereferenceThread(CsrThread); @@ -605,7 +671,7 @@ CsrApiRequestThread(IN PVOID Parameter) HardErrorMsg->Response = ResponseNotHandled; /* Check if there are free api threads */ - CsrCheckRequestThreads(); + CsrpCheckRequestThreads(); if (CsrpStaticThreadCount) { /* Loop every Server DLL */ @@ -615,10 +681,10 @@ CsrApiRequestThread(IN PVOID Parameter) ServerDll = CsrLoadedServerDll[i]; /* Check if it's valid and if it has a Hard Error Callback */ - if (ServerDll && ServerDll->HardErrorCallback) + if ((ServerDll) && (ServerDll->HardErrorCallback)) { /* Call it */ - (*ServerDll->HardErrorCallback)(CsrThread, HardErrorMsg); + ServerDll->HardErrorCallback(CsrThread, HardErrorMsg); /* If it's handled, get out of here */ if (HardErrorMsg->Response != ResponseNotHandled) break; @@ -627,17 +693,19 @@ CsrApiRequestThread(IN PVOID Parameter) } /* Increase the thread count */ - _InterlockedIncrement((PLONG)&CsrpStaticThreadCount); + _InterlockedIncrement(&CsrpStaticThreadCount); /* If the response was 0xFFFFFFFF, we'll ignore it */ if (HardErrorMsg->Response == 0xFFFFFFFF) { ReplyMsg = NULL; + ReplyPort = CsrApiPort; } else { CsrDereferenceThread(CsrThread); ReplyMsg = &ReceiveMsg; + ReplyPort = CsrApiPort; } } else @@ -655,8 +723,130 @@ CsrApiRequestThread(IN PVOID Parameter) CsrDereferenceThread(CsrThread); CsrReleaseProcessLock(); - /* FIXME: Handle the API */ + /* This is an API call, get the Server ID */ + ServerId = CSR_SERVER_ID_FROM_OPCODE(ReceiveMsg.Opcode); + /* Make sure that the ID is within limits, and the Server DLL loaded */ + ServerDll = NULL; + if ((ServerId >= CSR_SERVER_DLL_MAX) || + (!(ServerDll = CsrLoadedServerDll[ServerId]))) + { + /* We are beyond the Maximum Server ID */ + DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", + ServerId, ServerDll); + DbgBreakPoint(); + + ReplyPort = CsrApiPort; + ReplyMsg = &ReceiveMsg; + ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION; + CsrDereferenceThread(CsrThread); + continue; + } + + /* Get the API ID */ + ApiId = CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode); + + /* Normalize it with our Base ID */ + ApiId -= ServerDll->ApiBase; + + /* Make sure that the ID is within limits, and the entry exists */ + if (ApiId >= ServerDll->HighestApiSupported) + { + /* We are beyond the Maximum API ID, or it doesn't exist */ + DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n", + CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode), + &ServerDll->Name); + + ReplyPort = CsrApiPort; + ReplyMsg = &ReceiveMsg; + ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION; + CsrDereferenceThread(CsrThread); + continue; + } + + if (CsrDebug & 2) + { + DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n", + Teb->ClientId.UniqueThread, + ReceiveMsg.Header.ClientId.UniqueProcess, + ReceiveMsg.Header.ClientId.UniqueThread, + ServerDll->NameTable[ApiId], + CsrThread); + } + + /* Assume success */ + ReplyMsg = &ReceiveMsg; + ReceiveMsg.Status = STATUS_SUCCESS; + + /* Now we reply to a particular client */ + ReplyPort = CsrThread->Process->ClientPort; + + /* Check if there's a capture buffer */ + if (ReceiveMsg.CsrCaptureData) + { + /* Capture the arguments */ + if (!CsrCaptureArguments(CsrThread, &ReceiveMsg)) + { + /* Ignore this message if we failed to get the arguments */ + CsrDereferenceThread(CsrThread); + continue; + } + } + + /* Validation complete, start SEH */ + _SEH2_TRY + { + /* Make sure we have enough threads */ + CsrpCheckRequestThreads(); + + Teb->CsrClientThread = CsrThread; + + /* Call the API and get the result */ + Reply = 0; + ServerDll->DispatchTable[ApiId](&ReceiveMsg, &Reply); + + /* Increase the static thread count */ + _InterlockedIncrement(&CsrpStaticThreadCount); + + Teb->CsrClientThread = CurrentThread; + + if (Reply == 3) + { + ReplyMsg = NULL; + if (ReceiveMsg.CsrCaptureData) + { + CsrReleaseCapturedArguments(&ReceiveMsg); + } + CsrDereferenceThread(CsrThread); + ReplyPort = CsrApiPort; + } + else if (Reply == 2) + { + NtReplyPort(ReplyPort, &ReplyMsg->Header); + ReplyPort = CsrApiPort; + ReplyMsg = NULL; + CsrDereferenceThread(CsrThread); + } + else if (Reply == 1) + { + ReplyPort = CsrApiPort; + ReplyMsg = NULL; + } + else + { + if (ReceiveMsg.CsrCaptureData) + { + CsrReleaseCapturedArguments(&ReceiveMsg); + } + CsrDereferenceThread(CsrThread); + } + } + _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation())) + { + ReplyMsg = NULL; + ReplyPort = CsrApiPort; + } + _SEH2_END; } /* We're out of the loop for some reason, terminate! */ @@ -709,7 +899,7 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage) if (CsrProcess) { /* Reference the Process */ - CsrProcess->ReferenceCount++; + CsrLockedReferenceProcess(CsrThread->Process); /* Release the lock */ CsrReleaseProcessLock(); @@ -738,7 +928,7 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage) } /* Dereference the project */ - CsrProcess->ReferenceCount--; + CsrLockedDereferenceProcess(CsrProcess); } } @@ -760,10 +950,21 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage) AllowConnection, NULL, &RemotePortView); - - /* Check if the connection was established, or if we allowed it */ - if (NT_SUCCESS(Status) && AllowConnection) + if (!NT_SUCCESS(Status)) { + DPRINT1("CSRSS: NtAcceptConnectPort - failed. Status == %X\n", Status); + } + else if (AllowConnection) + { + if (CsrDebug & 2) + { + DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n", + ApiMessage->Header.ClientId.UniqueProcess, + ApiMessage->Header.ClientId.UniqueThread, + RemotePortView.ViewBase, + RemotePortView.ViewSize); + } + /* Set some Port Data in the Process */ CsrProcess->ClientPort = hPort; CsrProcess->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase; @@ -772,12 +973,16 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage) /* Complete the connection */ Status = NtCompleteConnectPort(hPort); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status); + } } - - /* The accept or complete could've failed, let debug builds know */ - if (!NT_SUCCESS(Status)) + else { - DPRINT1("CSRSS: Failure to accept connection. Status: %lx\n", Status); + DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n", + ApiMessage->Header.ClientId.UniqueProcess, + ApiMessage->Header.ClientId.UniqueThread); } /* Return status to caller */ @@ -804,8 +1009,8 @@ NTAPI CsrSbApiRequestThread(IN PVOID Parameter) { NTSTATUS Status; - SB_API_MESSAGE ReceiveMsg; - PSB_API_MESSAGE ReplyMsg = NULL; + SB_API_MSG ReceiveMsg; + PSB_API_MSG ReplyMsg = NULL; PVOID PortContext; ULONG MessageType; @@ -815,22 +1020,23 @@ CsrSbApiRequestThread(IN PVOID Parameter) /* Wait for a message to come in */ Status = NtReplyWaitReceivePort(CsrSbApiPort, &PortContext, - (PPORT_MESSAGE)ReplyMsg, - (PPORT_MESSAGE)&ReceiveMsg); + &ReplyMsg->h, + &ReceiveMsg.h); /* Check if we didn't get success */ - if(Status != STATUS_SUCCESS) + if (Status != STATUS_SUCCESS) { /* If we only got a warning, keep going */ if (NT_SUCCESS(Status)) continue; /* We failed big time, so start out fresh */ ReplyMsg = NULL; + DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status); continue; } /* Save the message type */ - MessageType = ReceiveMsg.Header.u2.s2.Type; + MessageType = ReceiveMsg.h.u2.s2.Type; /* Check if this is a connection request */ if (MessageType == LPC_CONNECTION_REQUEST) @@ -864,16 +1070,20 @@ CsrSbApiRequestThread(IN PVOID Parameter) * It's an API Message, check if it's within limits. If it's not, the * NT Behaviour is to set this to the Maximum API. */ - if (ReceiveMsg.Opcode > 4) ReceiveMsg.Opcode = 4; + if (ReceiveMsg.ApiNumber > SbpMaxApiNumber) + { + ReceiveMsg.ApiNumber = SbpMaxApiNumber; + DPRINT1("CSRSS: %lx is invalid Sb ApiNumber\n", ReceiveMsg.ApiNumber); + } /* Reuse the message */ ReplyMsg = &ReceiveMsg; /* Make sure that the message is supported */ - if (ReceiveMsg.Opcode < 4) + if (ReceiveMsg.ApiNumber < SbpMaxApiNumber) { /* Call the API */ - if (!(CsrServerSbApiDispatch[ReceiveMsg.Opcode])(&ReceiveMsg)) + if (!CsrServerSbApiDispatch[ReceiveMsg.ApiNumber](&ReceiveMsg)) { /* It failed, so return nothing */ ReplyMsg = NULL; @@ -882,7 +1092,7 @@ CsrSbApiRequestThread(IN PVOID Parameter) else { /* We don't support this API Number */ - ReplyMsg->Status = STATUS_NOT_IMPLEMENTED; + ReplyMsg->ReturnValue = STATUS_NOT_IMPLEMENTED; } } } @@ -905,7 +1115,7 @@ CsrSbApiRequestThread(IN PVOID Parameter) *--*/ NTSTATUS NTAPI -CsrSbApiHandleConnectionRequest(IN PSB_API_MESSAGE Message) +CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message) { NTSTATUS Status; REMOTE_PORT_VIEW RemotePortView; @@ -921,7 +1131,6 @@ CsrSbApiHandleConnectionRequest(IN PSB_API_MESSAGE Message) TRUE, NULL, &RemotePortView); - if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: Sb Accept Connection failed %lx\n", Status); @@ -929,7 +1138,8 @@ CsrSbApiHandleConnectionRequest(IN PSB_API_MESSAGE Message) } /* Complete the Connection */ - if (!NT_SUCCESS(Status = NtCompleteConnectPort(hPort))) + Status = NtCompleteConnectPort(hPort); + if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: Sb Complete Connection failed %lx\n",Status); } @@ -979,6 +1189,7 @@ CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg, (!(ServerDll = CsrLoadedServerDll[ServerId]))) { /* We are beyond the Maximum Server ID */ + DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", ServerId, ServerDll); ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION; return STATUS_ILLEGAL_FUNCTION; } @@ -992,14 +1203,26 @@ CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg, /* Make sure that the ID is within limits, and the entry exists */ if ((ApiId >= ServerDll->HighestApiSupported) || - (ServerDll->ValidTable && !ServerDll->ValidTable[ApiId])) + ((ServerDll->ValidTable) && !(ServerDll->ValidTable[ApiId]))) { /* We are beyond the Maximum API ID, or it doesn't exist */ + DPRINT1("CSRSS: %lx (%s) is invalid ApiTableIndex for %Z or is an " + "invalid API to call from the server.\n", + ServerDll->ValidTable[ApiId], + ((ServerDll->NameTable) && (ServerDll->NameTable[ApiId])) ? + ServerDll->NameTable[ApiId] : "*** UNKNOWN ***", &ServerDll->Name); + DbgBreakPoint(); ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION; return STATUS_ILLEGAL_FUNCTION; } } + if (CsrDebug & 2) + { + DPRINT1("CSRSS: %s Api Request received from server process\n", + ServerDll->NameTable[ApiId]); + } + /* Validation complete, start SEH */ _SEH2_TRY { @@ -1044,6 +1267,7 @@ CsrConnectToUser(VOID) STRING StartupName; PTEB Teb = NtCurrentTeb(); PCSR_THREAD CsrThread; + BOOLEAN Connected; /* Check if we didn't already find it */ if (!CsrClientThreadSetup) @@ -1069,10 +1293,25 @@ CsrConnectToUser(VOID) } /* Connect to user32 */ - CsrClientThreadSetup(); + _SEH2_TRY + { + Connected = CsrClientThreadSetup(); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Connected = FALSE; + } _SEH2_END; + + if (!Connected) + { + DPRINT1("CSRSS: CsrConnectToUser failed\n"); + return NULL; + } /* Save pointer to this thread in TEB */ + CsrAcquireProcessLock(); CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId); + CsrReleaseProcessLock(); if (CsrThread) Teb->CsrClientThread = CsrThread; /* Return it */ @@ -1124,13 +1363,10 @@ NTAPI CsrCaptureArguments(IN PCSR_THREAD CsrThread, IN PCSR_API_MESSAGE ApiMessage) { - PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL; - ULONG LocalLength = 0; - PCSR_CAPTURE_BUFFER RemoteCaptureBuffer = NULL; + PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL, RemoteCaptureBuffer = NULL; + ULONG LocalLength = 0, PointerCount = 0; SIZE_T BufferDistance = 0; - ULONG PointerCount = 0; - ULONG_PTR **PointerOffsets = NULL; - ULONG_PTR *CurrentPointer = NULL; + ULONG_PTR **PointerOffsets = NULL, *CurrentPointer = NULL; /* Use SEH to make sure this is valid */ _SEH2_TRY @@ -1144,6 +1380,7 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread, (((ULONG_PTR)LocalCaptureBuffer + LocalLength) >= CsrThread->Process->ClientViewBounds)) { /* Return failure */ + DPRINT1("*** CSRSS: CaptureBuffer outside of ClientView\n"); ApiMessage->Status = STATUS_INVALID_PARAMETER; _SEH2_YIELD(return FALSE); } @@ -1153,6 +1390,8 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread, LocalLength) ||(LocalLength > MAXWORD)) { /* Return failure */ + DPRINT1("*** CSRSS: CaptureBuffer %p has bad length\n", LocalCaptureBuffer); + DbgBreakPoint(); ApiMessage->Status = STATUS_INVALID_PARAMETER; _SEH2_YIELD(return FALSE); } @@ -1205,7 +1444,9 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread, else { /* Invalid pointer, fail */ - ApiMessage->Status = (ULONG)STATUS_INVALID_PARAMETER; + DPRINT1("*** CSRSS: CaptureBuffer MessagePointer outside of ClientView\n"); + DbgBreakPoint(); + ApiMessage->Status = STATUS_INVALID_PARAMETER; } } @@ -1251,12 +1492,10 @@ VOID NTAPI CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage) { - PCSR_CAPTURE_BUFFER RemoteCaptureBuffer; - PCSR_CAPTURE_BUFFER LocalCaptureBuffer; + PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer; SIZE_T BufferDistance; ULONG PointerCount; - ULONG_PTR **PointerOffsets; - ULONG_PTR *CurrentPointer; + ULONG_PTR **PointerOffsets, *CurrentPointer; /* Get the capture buffers */ RemoteCaptureBuffer = ApiMessage->CsrCaptureData; @@ -1276,7 +1515,8 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage) while (PointerCount) { /* Get the current pointer */ - if ((CurrentPointer = *PointerOffsets++)) + CurrentPointer = *PointerOffsets++; + if (CurrentPointer) { /* Add it to the CSR Message structure */ CurrentPointer += (ULONG_PTR)ApiMessage; @@ -1290,9 +1530,7 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage) } /* Copy the data back */ - RtlMoveMemory(LocalCaptureBuffer, - RemoteCaptureBuffer, - RemoteCaptureBuffer->Size); + RtlMoveMemory(LocalCaptureBuffer, RemoteCaptureBuffer, RemoteCaptureBuffer->Size); /* Free our allocated buffer */ RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer); @@ -1331,10 +1569,8 @@ CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, { PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData; SIZE_T BufferDistance; - ULONG PointerCount; - ULONG_PTR **PointerOffsets; - ULONG_PTR *CurrentPointer; - ULONG i; + ULONG PointerCount, i; + ULONG_PTR **PointerOffsets, *CurrentPointer; /* Make sure there are some arguments */ if (!ArgumentCount) return FALSE; @@ -1379,6 +1615,8 @@ CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, } /* Failure */ + DbgPrint("CSRSRV: Bad message buffer %p\n", ApiMessage); + DbgBreakPoint(); return FALSE; } @@ -1405,7 +1643,7 @@ NTAPI CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage, IN LPWSTR *MessageString) { - DPRINT("CSRSRV: %s called\n", __FUNCTION__); + DPRINT1("CSRSRV: %s called\n", __FUNCTION__); return FALSE; } diff --git a/reactos/subsystems/csr/csrsrv/csrsrv.rbuild b/reactos/subsystems/csr/csrsrv/csrsrv.rbuild deleted file mode 100644 index 3a215fda8a8..00000000000 --- a/reactos/subsystems/csr/csrsrv/csrsrv.rbuild +++ /dev/null @@ -1,18 +0,0 @@ - - - - - . - . - include/reactos/subsys - ntdll - pseh - api.c - init.c - process.c - server.c - session.c - thread.c - wait.c - srv.h - diff --git a/reactos/subsystems/csr/csrsrv/csrsrv.spec b/reactos/subsystems/csr/csrsrv/csrsrv2.spec similarity index 96% rename from reactos/subsystems/csr/csrsrv/csrsrv.spec rename to reactos/subsystems/csr/csrsrv/csrsrv2.spec index 6b68980350b..e3794208fe9 100644 --- a/reactos/subsystems/csr/csrsrv/csrsrv.spec +++ b/reactos/subsystems/csr/csrsrv/csrsrv2.spec @@ -3,7 +3,7 @@ @ stdcall CsrConnectToUser() @ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr) @ stdcall CsrCreateRemoteThread(ptr ptr) -@ stdcall CsrCreateThread(ptr ptr ptr) +@ stdcall CsrCreateThread(ptr ptr ptr long) @ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr) @ stdcall CsrDebugProcess(ptr) @ stdcall CsrDebugProcessStop(ptr) diff --git a/reactos/subsystems/csr/csrsrv/init.c b/reactos/subsystems/csr/csrsrv/init.c index 02e14cdb791..77667a6f4f5 100644 --- a/reactos/subsystems/csr/csrsrv/init.c +++ b/reactos/subsystems/csr/csrsrv/init.c @@ -25,168 +25,14 @@ HANDLE SessionObjectDirectory; HANDLE DosDevicesDirectory; HANDLE CsrInitializationEvent; SYSTEM_BASIC_INFORMATION CsrNtSysInfo; +ULONG CsrDebug; /* PRIVATE FUNCTIONS *********************************************************/ /*++ - * @name CsrPopulateDosDevicesDirectory + * @name CsrParseServerCommandLine * - * The CsrPopulateDosDevicesDirectory routine uses the DOS Device Map from the - * Kernel to populate the Dos Devices Object Directory for the session. - * - * @param TODO. - * - * @return TODO. - * - * @remarks TODO. - * - *--*/ -NTSTATUS -NTAPI -CsrPopulateDosDevicesDirectory(IN HANDLE hDosDevicesDirectory, - IN PPROCESS_DEVICEMAP_INFORMATION DeviceMap) -{ - WCHAR SymLinkBuffer[0x1000]; - UNICODE_STRING GlobalString; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hDirectory = 0; - NTSTATUS Status; - ULONG ReturnLength = 0; - ULONG BufferLength = 0x4000; - ULONG Context; - POBJECT_DIRECTORY_INFORMATION QueryBuffer; - HANDLE hSymLink; - UNICODE_STRING LinkTarget; - - /* Initialize the Global String */ - RtlInitUnicodeString(&GlobalString, GLOBAL_ROOT); - - /* Initialize the Object Attributes */ - InitializeObjectAttributes(&ObjectAttributes, - &GlobalString, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - /* Open the directory */ - Status = NtOpenDirectoryObject(&hDirectory, - DIRECTORY_QUERY, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) return Status; - - /* Allocate memory */ - QueryBuffer = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, 0x4000); - if (!QueryBuffer) return STATUS_NO_MEMORY; - - /* Start query loop */ - while (TRUE) - { - /* Query the Directory */ - Status = NtQueryDirectoryObject(hDirectory, - QueryBuffer, - BufferLength, - FALSE, - FALSE, - &Context, - &ReturnLength); - - /* Check for the status */ - if (NT_SUCCESS(Status)) - { - /* Make sure it has a name */ - if (!QueryBuffer->Name.Buffer[0]) continue; - - /* Check if it's actually a symbolic link */ - if (wcscmp(QueryBuffer->TypeName.Buffer, SYMLINK_NAME)) - { - /* It is, open it */ - InitializeObjectAttributes(&ObjectAttributes, - &QueryBuffer->Name, - OBJ_CASE_INSENSITIVE, - NULL, - hDirectory); - Status = NtOpenSymbolicLinkObject(&hSymLink, - SYMBOLIC_LINK_QUERY, - &ObjectAttributes); - if (NT_SUCCESS(Status)) - { - /* Setup the Target String */ - LinkTarget.Length = 0; - LinkTarget.MaximumLength = sizeof(SymLinkBuffer); - LinkTarget.Buffer = SymLinkBuffer; - - /* Query the target */ - Status = NtQuerySymbolicLinkObject(hSymLink, - &LinkTarget, - &ReturnLength); - - /* Close the handle */ - NtClose(hSymLink); - - } - } - } - /* FIXME: Loop never ends! */ - } -} - -/*++ - * @name CsrLoadServerDllFromCommandLine - * - * The CsrLoadServerDllFromCommandLine routine loads a Server DLL from the - * CSRSS command-line in the registry. - * - * @param KeyValue - * Pointer to the specially formatted string for this Server DLL. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrLoadServerDllFromCommandLine(PCHAR KeyValue) -{ - PCHAR EntryPoint = NULL; - ULONG DllIndex = 0; - PCHAR ServerString = KeyValue; - NTSTATUS Status; - - /* Loop the command line */ - while (*ServerString) - { - /* Check for the Entry Point */ - if ((*ServerString == ':') && (!EntryPoint)) - { - /* Found it. Add a nullchar and save it */ - *ServerString++ = '\0'; - EntryPoint = ServerString; - } - - /* Check for the Dll Index */ - if (*ServerString++ == ',') - { - /* Convert it to a ULONG */ - Status = RtlCharToInteger(ServerString, 10, &DllIndex); - - /* Add a null char if it was valid */ - if (NT_SUCCESS(Status)) ServerString[-1] = '\0'; - - /* We're done here */ - break; - } - } - - /* We've got the name, entrypoint and index, load it */ - return CsrLoadServerDll(KeyValue, EntryPoint, DllIndex); -} - -/*++ - * @name CsrpParseCommandLine - * - * The CsrpParseCommandLine routine parses the CSRSS command-line in the + * The CsrParseServerCommandLine routine parses the CSRSS command-line in the * registry and performs operations for each entry found. * * @param ArgumentCount @@ -203,13 +49,14 @@ CsrLoadServerDllFromCommandLine(PCHAR KeyValue) *--*/ NTSTATUS FASTCALL -CsrpParseCommandLine(IN ULONG ArgumentCount, - IN PCHAR Arguments[]) +CsrParseServerCommandLine(IN ULONG ArgumentCount, + IN PCHAR Arguments[]) { NTSTATUS Status; - PCHAR ParameterName = NULL; - PCHAR ParameterValue = NULL; - ULONG i; + PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString; + ULONG i, DllIndex; + ANSI_STRING AnsiString; + OBJECT_ATTRIBUTES ObjectAttributes; /* Set the Defaults */ CsrTotalPerProcessDataLength = 0; @@ -224,8 +71,9 @@ CsrpParseCommandLine(IN ULONG ArgumentCount, DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n", Status); - /* It's not fatal if the SID is 0 */ - if (SessionId != 0) return Status; + /* It's not fatal if the session ID isn't zero */ + if (SessionId) return Status; + ASSERT(NT_SUCCESS(Status)); } /* Loop through every argument */ @@ -233,19 +81,48 @@ CsrpParseCommandLine(IN ULONG ArgumentCount, { /* Split Name and Value */ ParameterName = Arguments[i]; + ParameterValue = NULL; ParameterValue = strchr(ParameterName, L'='); - *ParameterValue++ = '\0'; + if (ParameterValue) *ParameterValue++ = '\0'; DPRINT("Name=%S, Value=%S\n", ParameterName, ParameterValue); /* Check for Object Directory */ if (!_stricmp(ParameterName, "ObjectDirectory")) { - CsrCreateObjectDirectory(ParameterValue); + /* Check if a session ID is specified */ + if (SessionId) + { + DPRINT1("Sessions not yet implemented\n"); + ASSERT(SessionId); + } + + /* Initialize the directory name */ + RtlInitAnsiString(&AnsiString, ParameterValue); + Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName, + &AnsiString, + TRUE); + ASSERT(NT_SUCCESS(Status) || SessionId != 0); + if (!NT_SUCCESS(Status)) return Status; + + /* Create it */ + InitializeObjectAttributes(&ObjectAttributes, + &CsrDirectoryName, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE | + (SessionId) ? 0 : OBJ_PERMANENT, + NULL, + NULL); + Status = NtCreateDirectoryObject(&CsrObjectDirectory, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) return Status; + + /* Secure it */ + Status = CsrSetDirectorySecurity(CsrObjectDirectory); + if (!NT_SUCCESS(Status)) return Status; } - else if(!_stricmp(ParameterName, "SubSystemType")) + else if (!_stricmp(ParameterName, "SubSystemType")) { /* Ignored */ - Status = STATUS_SUCCESS; } else if (!_stricmp(ParameterName, "MaxRequestThreads")) { @@ -260,25 +137,69 @@ CsrpParseCommandLine(IN ULONG ArgumentCount, } else if (!_stricmp(ParameterName, "ProfileControl")) { - CsrProfileControl = (!_stricmp(ParameterValue, "On")) ? TRUE : FALSE; + /* Ignored */ } else if (!_stricmp(ParameterName, "SharedSection")) { /* Craete the Section */ Status = CsrSrvCreateSharedSection(ParameterValue); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n", + ParameterName, ParameterValue, Status); + return Status; + } /* Load us */ Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER); } else if (!_stricmp(ParameterName, "ServerDLL")) { - /* Parse the Command-Line and load this DLL */ - Status = CsrLoadServerDllFromCommandLine(ParameterValue); + /* Loop the command line */ + EntryPoint = NULL; + Status = STATUS_INVALID_PARAMETER; + ServerString = ParameterValue; + while (*ServerString) + { + /* Check for the Entry Point */ + if ((*ServerString == ':') && (!EntryPoint)) + { + /* Found it. Add a nullchar and save it */ + *ServerString++ = ANSI_NULL; + EntryPoint = ServerString; + } + + /* Check for the Dll Index */ + if (*ServerString++ == ',') break; + } + + /* Did we find something to load? */ + if (!*ServerString) + { + DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n", + ParameterValue, Status); + return Status; + } + + /* Convert it to a ULONG */ + Status = RtlCharToInteger(ServerString, 10, &DllIndex); + + /* Add a null char if it was valid */ + if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL; + + /* Load it */ + if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint); + Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n", + ParameterValue, Status); + return Status; + } } else if (!_stricmp(ParameterName, "Windows")) { /* Ignored */ - Status = STATUS_SUCCESS; } else { @@ -291,59 +212,6 @@ CsrpParseCommandLine(IN ULONG ArgumentCount, return Status; } -/*++ - * @name CsrCreateObjectDirectory - * - * The CsrCreateObjectDirectory creates the Object Directory on the CSRSS - * command-line from the registry. - * - * @param ObjectDirectory - * Pointer to the name of the Object Directory to create. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrCreateObjectDirectory(IN PCHAR ObjectDirectory) -{ - NTSTATUS Status = STATUS_SUCCESS; - ANSI_STRING TempString; - OBJECT_ATTRIBUTES DirectoryAttributes; - - DPRINT("CSRSRV:%s(%s) called\n", __FUNCTION__, ObjectDirectory); - - /* Convert the parameter to our Global Unicode name */ - RtlInitAnsiString(&TempString, ObjectDirectory); - Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName, &TempString, TRUE); - - /* Initialize the attributes for the Directory */ - InitializeObjectAttributes(&DirectoryAttributes, - &CsrDirectoryName, - OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - /* Create it */ - Status = NtCreateDirectoryObject(&CsrObjectDirectory, - DIRECTORY_ALL_ACCESS, - &DirectoryAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n", - __FUNCTION__, Status); - } - - /* Set the Security */ - Status = CsrSetDirectorySecurity(CsrObjectDirectory); - - /* Return */ - return Status; -} - /*++ * @name CsrCreateLocalSystemSD * @@ -365,86 +233,66 @@ CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd) { SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY}; PSID SystemSid; - ULONG SidLength; - PSECURITY_DESCRIPTOR SecurityDescriptor; + ULONG Length; + PSECURITY_DESCRIPTOR SystemSd; PACL Dacl; NTSTATUS Status; /* Initialize the System SID */ - RtlAllocateAndInitializeSid(&NtSidAuthority, - 1, + RtlAllocateAndInitializeSid(&NtSidAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 0, 0, 0, 0, 0, 0, 0, &SystemSid); /* Get the length of the SID */ - SidLength = RtlLengthSid(SystemSid); + Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); /* Allocate a buffer for the Security Descriptor, with SID and DACL */ - SecurityDescriptor = RtlAllocateHeap(CsrHeap, - 0, - SECURITY_DESCRIPTOR_MIN_LENGTH + - sizeof(ACL) + SidLength + - sizeof(ACCESS_ALLOWED_ACE)); + SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length); /* Set the pointer to the DACL */ - Dacl = (PACL)((ULONG_PTR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH); + Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH); /* Now create the SD itself */ - Status = RtlCreateSecurityDescriptor(SecurityDescriptor, - SECURITY_DESCRIPTOR_REVISION); + Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { /* Fail */ - RtlFreeHeap(CsrHeap, 0, SecurityDescriptor); + RtlFreeHeap(CsrHeap, 0, SystemSd); return Status; } /* Create the DACL for it*/ - RtlCreateAcl(Dacl, - sizeof(ACL) + SidLength + sizeof(ACCESS_ALLOWED_ACE), - ACL_REVISION2); + RtlCreateAcl(Dacl, Length, ACL_REVISION2); /* Create the ACE */ - Status = RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - PORT_ALL_ACCESS, - SystemSid); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid); if (!NT_SUCCESS(Status)) { /* Fail */ - RtlFreeHeap(CsrHeap, 0, SecurityDescriptor); + RtlFreeHeap(CsrHeap, 0, SystemSd); return Status; } /* Clear the DACL in the SD */ - Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, - TRUE, - Dacl, - FALSE); + Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE); if (!NT_SUCCESS(Status)) { /* Fail */ - RtlFreeHeap(CsrHeap, 0, SecurityDescriptor); + RtlFreeHeap(CsrHeap, 0, SystemSd); return Status; } /* Free the SID and return*/ RtlFreeSid(SystemSid); - *LocalSystemSd = SecurityDescriptor; + *LocalSystemSd = SystemSd; return Status; } /*++ - * @name CsrGetDosDevicesSd + * @name GetDosDevicesProtection * - * The CsrGetDosDevicesSd creates a security descriptor for the DOS Devices + * The GetDosDevicesProtection creates a security descriptor for the DOS Devices * Object Directory. * * @param DosDevicesSd @@ -459,7 +307,7 @@ CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd) *--*/ NTSTATUS NTAPI -CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd) +GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd) { SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY}; @@ -474,61 +322,34 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd) PACCESS_ALLOWED_ACE Ace; HANDLE hKey; NTSTATUS Status; - ULONG ResultLength, SidLength; + ULONG ResultLength, SidLength, AclLength; /* Create the SD */ RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION); /* Initialize the System SID */ - RtlAllocateAndInitializeSid(&NtSidAuthority, - 1, + RtlAllocateAndInitializeSid(&NtSidAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 0, 0, 0, 0, 0, 0, 0, &SystemSid); /* Initialize the World SID */ - RtlAllocateAndInitializeSid(&WorldAuthority, - 1, + RtlAllocateAndInitializeSid(&WorldAuthority, 1, SECURITY_WORLD_RID, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 0, 0, 0, 0, 0, 0, 0, &WorldSid); /* Initialize the Admin SID */ - RtlAllocateAndInitializeSid(&NtSidAuthority, - 2, + RtlAllocateAndInitializeSid(&NtSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, - 0, - 0, - 0, - 0, - 0, - 0, + 0, 0, 0, 0, 0, 0, &AdminSid); /* Initialize the Creator SID */ - RtlAllocateAndInitializeSid(&CreatorAuthority, - 1, + RtlAllocateAndInitializeSid(&CreatorAuthority, 1, SECURITY_CREATOR_OWNER_RID, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 0, 0, 0, 0, 0, 0, 0, &CreatorSid); /* Open the Session Manager Key */ @@ -538,11 +359,10 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd) OBJ_CASE_INSENSITIVE, NULL, NULL); - if (NT_SUCCESS(Status = NtOpenKey(&hKey, - KEY_READ, - &ObjectAttributes))) + Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes); + if (NT_SUCCESS(Status)) { - /* Read the ProtectionMode. See http://support.microsoft.com/kb/q218473/ */ + /* Read the key value */ RtlInitUnicodeString(&KeyName, L"ProtectionMode"); Status = NtQueryValueKey(hKey, &KeyName, @@ -553,8 +373,8 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd) /* Make sure it's what we expect it to be */ KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer; - if ((KeyValuePartialInfo->Type == REG_DWORD) && - (*(PULONG)KeyValuePartialInfo->Data != 0)) + if ((KeyValuePartialInfo->Type == REG_DWORD) && + (*(PULONG)KeyValuePartialInfo->Data)) { /* Save the Protection Mode */ ProtectionMode = *(PULONG)KeyValuePartialInfo->Data; @@ -570,110 +390,49 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd) /* Calculate SID Lengths */ SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) + RtlLengthSid(AdminSid); + AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength; /* Allocate memory for the DACL */ - Dacl = RtlAllocateHeap(CsrHeap, - HEAP_ZERO_MEMORY, - sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + - SidLength); + Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength); - /* Create it */ - Status = RtlCreateAcl(Dacl, - sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + - SidLength, - ACL_REVISION2); + /* Build the ACL and add 3 ACEs */ + Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid); - /* Give full access to the System */ - Status = RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - GENERIC_ALL, - SystemSid); - - /* Get the ACE back */ + /* Edit the ACEs to make them inheritable */ Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace); - - /* Add some flags to it for the Admin SID */ - Ace->Header.AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE); - - /* Add the ACE to the Admin SID */ - Status = RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - GENERIC_ALL, - AdminSid); - - /* Get the ACE back */ + Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace); - - /* Add some flags to it for the Creator SID */ - Ace->Header.AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE); - - /* Add the ACE to the Admin SID */ - Status = RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - GENERIC_ALL, - CreatorSid); - - /* Get the ACE back */ + Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); - - /* Add some flags to it for the SD */ - Ace->Header.AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | - INHERIT_ONLY_ACE); + Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; /* Set this DACL with the SD */ - Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, - TRUE, - Dacl, - FALSE); + Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); } else { /* Calculate SID Lengths */ SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid); + AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength; /* Allocate memory for the DACL */ - Dacl = RtlAllocateHeap(CsrHeap, - HEAP_ZERO_MEMORY, - sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + - SidLength); + Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength); - /* Create it */ - Status = RtlCreateAcl(Dacl, - sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + - SidLength, - ACL_REVISION2); + /* Build the ACL and add 3 ACEs */ + Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid); - /* Give RWE access to the World */ - Status = RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - GENERIC_READ | GENERIC_WRITE | - GENERIC_EXECUTE, - WorldSid); - - /* Give full access to the System */ - Status = RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - GENERIC_ALL, - SystemSid); - - /* Give full access to the World */ - Status = RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - GENERIC_ALL, - WorldSid); - - /* Get the ACE back */ + /* Edit the last ACE to make it inheritable */ Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); - - /* Add some flags to it for the SD */ - Ace->Header.AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | - INHERIT_ONLY_ACE); + Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; /* Set this DACL with the SD */ - Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, - TRUE, - Dacl, - FALSE); + Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); } /* FIXME: failure cases! Fail: */ @@ -692,10 +451,10 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd) } /*++ - * @name CsrFreeDosDevicesSd + * @name FreeDosDevicesProtection * - * The CsrFreeDosDevicesSd frees the security descriptor that was created - * by CsrGetDosDevicesSd + * The FreeDosDevicesProtection frees the security descriptor that was created + * by GetDosDevicesProtection * * @param DosDevicesSd * Pointer to the security descriptor to free. @@ -707,20 +466,20 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd) *--*/ VOID NTAPI -CsrFreeDosDevicesSd(IN PSECURITY_DESCRIPTOR DosDevicesSd) +FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd) { PACL Dacl; BOOLEAN Present, Default; NTSTATUS Status; /* Get the DACL corresponding to this SD */ - Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, - &Present, - &Dacl, - &Default); + Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default); + ASSERT(NT_SUCCESS(Status)); + ASSERT(Present); + ASSERT(Dacl != NULL); /* Free it */ - if (NT_SUCCESS(Status) && Dacl) RtlFreeHeap(CsrHeap, 0, Dacl); + if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl); } /*++ @@ -742,34 +501,30 @@ NTSTATUS NTAPI CsrCreateSessionObjectDirectory(IN ULONG Session) { - WCHAR SessionBuffer[512]; - WCHAR BnoBuffer[512]; - UNICODE_STRING SessionString; - UNICODE_STRING BnoString; + WCHAR SessionBuffer[512], BnoBuffer[512]; + UNICODE_STRING SessionString, BnoString; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE BnoHandle; SECURITY_DESCRIPTOR DosDevicesSd; NTSTATUS Status; - /* Generate the Session BNOLINKS Directory */ + /* Generate the Session BNOLINKS Directory name */ swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT); RtlInitUnicodeString(&SessionString, SessionBuffer); - /* Initialize the attributes for the Directory */ + /* Create it */ InitializeObjectAttributes(&ObjectAttributes, &SessionString, - OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, NULL); - - /* Create it */ Status = NtCreateDirectoryObject(&BNOLinksDirectory, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { - DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n", - __FUNCTION__, Status); + DPRINT1("CSRSS: NtCreateDirectoryObject failed in " + "CsrCreateSessionObjectDirectory - status = %lx\n", Status); return Status; } @@ -782,85 +537,74 @@ CsrCreateSessionObjectDirectory(IN ULONG Session) { /* Not the first, so the name will be slighly more complex */ swprintf(BnoBuffer, L"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT, Session); + RtlInitUnicodeString(&BnoString, BnoBuffer); } else { /* Use the direct name */ - RtlCopyMemory(BnoBuffer, L"\\BaseNamedObjects", 36); + RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects"); } - /* Create the Unicode String for the BNO SymLink */ - RtlInitUnicodeString(&BnoString, BnoBuffer); - - /* Initialize the attributes for the SymLink */ + /* Create the symlink */ InitializeObjectAttributes(&ObjectAttributes, &SessionString, - OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, BNOLinksDirectory, NULL); - - /* Create it */ Status = NtCreateSymbolicLinkObject(&BnoHandle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes, &BnoString); if (!NT_SUCCESS(Status)) { - DPRINT1("CSRSRV:%s: fatal: NtCreateSymbolicLinkObject failed (Status=0x%08lx)\n", - __FUNCTION__, Status); + DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in " + "CsrCreateSessionObjectDirectory - status = %lx\n", Status); return Status; } /* Create the \DosDevices Security Descriptor */ - CsrGetDosDevicesSd(&DosDevicesSd); + Status = GetDosDevicesProtection(&DosDevicesSd); + if (!NT_SUCCESS(Status)) return Status; /* Now create a directory for this session */ swprintf(SessionBuffer, L"%ws\\%ld", SESSION_ROOT, Session); RtlInitUnicodeString(&SessionString, SessionBuffer); - /* Initialize the attributes for the Directory */ + /* Create the directory */ InitializeObjectAttributes(&ObjectAttributes, &SessionString, - OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, 0, &DosDevicesSd); - - /* Create it */ Status = NtCreateDirectoryObject(&SessionObjectDirectory, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { - DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n", - __FUNCTION__, Status); - /* Release the Security Descriptor */ - CsrFreeDosDevicesSd(&DosDevicesSd); + DPRINT1("CSRSS: NtCreateDirectoryObject failed in " + "CsrCreateSessionObjectDirectory - status = %lx\n", Status); + FreeDosDevicesProtection(&DosDevicesSd); return Status; } /* Next, create a directory for this session's DOS Devices */ - /* Now create a directory for this session */ RtlInitUnicodeString(&SessionString, L"DosDevices"); - - /* Initialize the attributes for the Directory */ InitializeObjectAttributes(&ObjectAttributes, &SessionString, - OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE, - 0, + OBJ_CASE_INSENSITIVE, + SessionObjectDirectory, &DosDevicesSd); - - /* Create it */ Status = NtCreateDirectoryObject(&DosDevicesDirectory, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { - DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n", - __FUNCTION__, Status); + DPRINT1("CSRSS: NtCreateDirectoryObject failed in " + "CsrCreateSessionObjectDirectory - status = %lx\n", Status); } /* Release the Security Descriptor */ - CsrFreeDosDevicesSd(&DosDevicesSd); + FreeDosDevicesProtection(&DosDevicesSd); /* Return */ return Status; @@ -885,76 +629,54 @@ NTAPI CsrSetProcessSecurity(VOID) { NTSTATUS Status; - HANDLE hToken; - ULONG ReturnLength; - PTOKEN_USER TokenUserInformation; - PSECURITY_DESCRIPTOR SecurityDescriptor; + HANDLE hToken, hProcess = NtCurrentProcess(); + ULONG ReturnLength, Length; + PTOKEN_USER TokenInfo = NULL; + PSECURITY_DESCRIPTOR ProcSd = NULL; PACL Dacl; + PSID UserSid; /* Open our token */ - Status = NtOpenProcessToken(NtCurrentProcess(), - TOKEN_QUERY, - &hToken); - if (!NT_SUCCESS(Status)) return Status; + Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken); + if (!NT_SUCCESS(Status)) goto Quickie; /* Get the Token User Length */ - NtQueryInformationToken(hToken, - TokenUser, - NULL, - 0, - &ReturnLength); + NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length); /* Allocate space for it */ - TokenUserInformation = RtlAllocateHeap(CsrHeap, - HEAP_ZERO_MEMORY, - ReturnLength); + TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length); + if (!TokenInfo) + { + Status = STATUS_NO_MEMORY; + goto Quickie; + } /* Now query the data */ - Status = NtQueryInformationToken(hToken, - TokenUser, - TokenUserInformation, - ReturnLength, - &ReturnLength); - - /* Close the handle */ + Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length); NtClose(hToken); - - /* Make sure that we got the data */ - if (!NT_SUCCESS(Status)) - { - /* FAil */ - RtlFreeHeap(CsrHeap, 0, TokenUserInformation); - return Status; - } + if (!NT_SUCCESS(Status)) goto Quickie; /* Now check the SID Length */ - ReturnLength = RtlLengthSid(TokenUserInformation->User.Sid); + UserSid = TokenInfo->User.Sid; + ReturnLength = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); /* Allocate a buffer for the Security Descriptor, with SID and DACL */ - SecurityDescriptor = RtlAllocateHeap(CsrHeap, - HEAP_ZERO_MEMORY, - SECURITY_DESCRIPTOR_MIN_LENGTH + - sizeof(ACL) + ReturnLength + - sizeof(ACCESS_ALLOWED_ACE)); - - /* Set the pointer to the DACL */ - Dacl = (PACL)((ULONG_PTR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH); - - /* Now create the SD itself */ - Status = RtlCreateSecurityDescriptor(SecurityDescriptor, - SECURITY_DESCRIPTOR_REVISION); - if (!NT_SUCCESS(Status)) + ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length); + if (!ProcSd) { - /* Fail */ - RtlFreeHeap(CsrHeap, 0, SecurityDescriptor); - RtlFreeHeap(CsrHeap, 0, TokenUserInformation); - return Status; + Status = STATUS_NO_MEMORY; + goto Quickie; } + /* Set the pointer to the DACL */ + Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH); + + /* Now create the SD itself */ + Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION); + if (!NT_SUCCESS(Status)) goto Quickie; + /* Create the DACL for it*/ - RtlCreateAcl(Dacl, - sizeof(ACL) + ReturnLength + sizeof(ACCESS_ALLOWED_ACE), - ACL_REVISION2); + RtlCreateAcl(Dacl, Length, ACL_REVISION2); /* Create the ACE */ Status = RtlAddAccessAllowedAce(Dacl, @@ -963,36 +685,20 @@ CsrSetProcessSecurity(VOID) PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE | PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME | PROCESS_QUERY_INFORMATION | READ_CONTROL, - TokenUserInformation->User.Sid); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - RtlFreeHeap(CsrHeap, 0, SecurityDescriptor); - RtlFreeHeap(CsrHeap, 0, TokenUserInformation); - return Status; - } + UserSid); + if (!NT_SUCCESS(Status)) goto Quickie; /* Clear the DACL in the SD */ - Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, - TRUE, - Dacl, - FALSE); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - RtlFreeHeap(CsrHeap, 0, SecurityDescriptor); - RtlFreeHeap(CsrHeap, 0, TokenUserInformation); - return Status; - } + Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE); + if (!NT_SUCCESS(Status)) goto Quickie; /* Write the SD into the Process */ - Status = NtSetSecurityObject(NtCurrentProcess(), - DACL_SECURITY_INFORMATION, - SecurityDescriptor); + Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd); /* Free the memory and return */ - RtlFreeHeap(CsrHeap, 0, SecurityDescriptor); - RtlFreeHeap(CsrHeap, 0, TokenUserInformation); +Quickie: + if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd); + RtlFreeHeap(CsrHeap, 0, TokenInfo); return Status; } @@ -1049,7 +755,6 @@ CsrServerInitialization(ULONG ArgumentCount, ULONG i = 0; PVOID ProcessData; PCSR_SERVER_DLL ServerDll; - DPRINT("CSRSRV: %s called\n", __FUNCTION__); /* Create the Init Event */ @@ -1058,22 +763,40 @@ CsrServerInitialization(ULONG ArgumentCount, NULL, SynchronizationEvent, FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n", + __FUNCTION__, Status); + return Status; + } /* Cache System Basic Information so we don't always request it */ Status = NtQuerySystemInformation(SystemBasicInformation, &CsrNtSysInfo, sizeof(SYSTEM_BASIC_INFORMATION), NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n", + __FUNCTION__, Status); + return Status; + } /* Save our Heap */ CsrHeap = RtlGetProcessHeap(); /* Set our Security Descriptor to protect the process */ - CsrSetProcessSecurity(); + Status = CsrSetProcessSecurity(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n", + __FUNCTION__, Status); + return Status; + } /* Set up Session Support */ - Status = CsrInitializeNtSessions(); - if(!NT_SUCCESS(Status)) + Status = CsrInitializeNtSessionList(); + if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n", __FUNCTION__, Status); @@ -1081,27 +804,39 @@ CsrServerInitialization(ULONG ArgumentCount, } /* Set up Process Support */ - Status = CsrInitializeProcesses(); - if(!NT_SUCCESS(Status)) + Status = CsrInitializeProcessStructure(); + if (!NT_SUCCESS(Status)) { - DPRINT1("CSRSRV:%s: CsrInitializeProcesses failed (Status=%08lx)\n", + DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n", __FUNCTION__, Status); return Status; } /* Parse the command line */ - CsrpParseCommandLine(ArgumentCount, Arguments); + Status = CsrParseServerCommandLine(ArgumentCount, Arguments); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n", + __FUNCTION__, Status); + return Status; + } /* All Server DLLs are now loaded, allocate a heap for the Root Process */ ProcessData = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, CsrTotalPerProcessDataLength); + if (!ProcessData) + { + DPRINT1("CSRSRV:%s: RtlAllocateHeap failed (Status=%08lx)\n", + __FUNCTION__, STATUS_NO_MEMORY); + return STATUS_NO_MEMORY; + } /* * Our Root Process was never officially initalized, so write the data * for each Server DLL manually. */ - for(i = 0; i < CSR_SERVER_DLL_MAX; i++) + for (i = 0; i < CSR_SERVER_DLL_MAX; i++) { /* Get the current Server */ ServerDll = CsrLoadedServerDll[i]; @@ -1124,7 +859,7 @@ CsrServerInitialization(ULONG ArgumentCount, } /* Now initialize the Root Process manually as well */ - for(i = 0; i < CSR_SERVER_DLL_MAX; i++) + for (i = 0; i < CSR_SERVER_DLL_MAX; i++) { /* Get the current Server */ ServerDll = CsrLoadedServerDll[i]; @@ -1139,7 +874,7 @@ CsrServerInitialization(ULONG ArgumentCount, /* Now initialize our API Port */ Status = CsrApiPortInitialize(); - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n", __FUNCTION__, Status); @@ -1148,7 +883,7 @@ CsrServerInitialization(ULONG ArgumentCount, /* Initialize the API Port for SM communication */ Status = CsrSbApiPortInitialize(); - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n", __FUNCTION__, Status); @@ -1160,7 +895,7 @@ CsrServerInitialization(ULONG ArgumentCount, CsrSbApiPort, IMAGE_SUBSYSTEM_WINDOWS_GUI, &CsrSmApiPort); - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n", __FUNCTION__, Status); @@ -1168,19 +903,33 @@ CsrServerInitialization(ULONG ArgumentCount, } /* Finito! Signal the event */ - NtSetEvent(CsrInitializationEvent, NULL); + Status = NtSetEvent(CsrInitializationEvent, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n", + __FUNCTION__, Status); + return Status; + } + + /* Close the event handle now */ NtClose(CsrInitializationEvent); /* Have us handle Hard Errors */ - NtSetDefaultHardErrorPort(CsrApiPort); - + Status = NtSetDefaultHardErrorPort(CsrApiPort); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n", + __FUNCTION__, Status); + return Status; + } + /* Return status */ return Status; } /*++ * @name CsrPopulateDosDevices - * @implemented NT5.1 + * @unimplemented NT5.1 * * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel * to populate the Dos Devices Object Directory for the session. @@ -1196,35 +945,15 @@ VOID NTAPI CsrPopulateDosDevices(VOID) { - NTSTATUS Status; - PROCESS_DEVICEMAP_INFORMATION OldDeviceMap; - PROCESS_DEVICEMAP_INFORMATION NewDeviceMap; - - /* Query the Device Map */ - Status = NtQueryInformationProcess(NtCurrentProcess(), - ProcessDeviceMap, - &OldDeviceMap.Query, - sizeof(PROCESS_DEVICEMAP_INFORMATION), - NULL); - if (!NT_SUCCESS(Status)) return; - - /* Set the new one */ - NewDeviceMap.Set.DirectoryHandle = DosDevicesDirectory; - Status = NtSetInformationProcess(NtCurrentProcess(), - ProcessDeviceMap, - &NewDeviceMap, - sizeof(ULONG)); - if (!NT_SUCCESS(Status)) return; - - /* Populate the Directory */ - CsrPopulateDosDevicesDirectory(DosDevicesDirectory, &OldDeviceMap); + DPRINT1("Deprecated API\n"); + return; } BOOL NTAPI -DllMainCRTStartup(HANDLE hDll, - DWORD dwReason, - LPVOID lpReserved) +DllMain(IN HANDLE hDll, + IN DWORD dwReason, + IN LPVOID lpReserved) { /* We don't do much */ UNREFERENCED_PARAMETER(hDll); diff --git a/reactos/subsystems/csr/csrsrv/process.c b/reactos/subsystems/csr/csrsrv/process.c index 1de2286b549..ea75dd720c8 100644 --- a/reactos/subsystems/csr/csrsrv/process.c +++ b/reactos/subsystems/csr/csrsrv/process.c @@ -22,6 +22,84 @@ ULONG CsrTotalPerProcessDataLength; /* PRIVATE FUNCTIONS *********************************************************/ +/*++ + * @name ProtectHandle + * @implemented NT5.2 + * + * The ProtectHandle routine protects an object handle against closure. + * + * @return TRUE or FALSE. + * + * @remarks None. + * + *--*/ +BOOLEAN +NTAPI +ProtectHandle(IN HANDLE ObjectHandle) +{ + NTSTATUS Status; + OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo; + + /* Query current state */ + Status = NtQueryObject(ObjectHandle, + ObjectHandleFlagInformation, + &HandleInfo, + sizeof(HandleInfo), + NULL); + if (NT_SUCCESS(Status)) + { + /* Enable protect from close */ + HandleInfo.ProtectFromClose = TRUE; + Status = NtSetInformationObject(ObjectHandle, + ObjectHandleFlagInformation, + &HandleInfo, + sizeof(HandleInfo)); + if (NT_SUCCESS(Status)) return TRUE; + } + + /* We failed to or set the state */ + return FALSE; +} + +/*++ + * @name UnProtectHandle + * @implemented NT5.2 + * + * The UnProtectHandle routine unprotects an object handle against closure. + * + * @return TRUE or FALSE. + * + * @remarks None. + * + *--*/ +BOOLEAN +NTAPI +UnProtectHandle(IN HANDLE ObjectHandle) +{ + NTSTATUS Status; + OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo; + + /* Query current state */ + Status = NtQueryObject(ObjectHandle, + ObjectHandleFlagInformation, + &HandleInfo, + sizeof(HandleInfo), + NULL); + if (NT_SUCCESS(Status)) + { + /* Disable protect from close */ + HandleInfo.ProtectFromClose = FALSE; + Status = NtSetInformationObject(ObjectHandle, + ObjectHandleFlagInformation, + &HandleInfo, + sizeof(HandleInfo)); + if (NT_SUCCESS(Status)) return TRUE; + } + + /* We failed to or set the state */ + return FALSE; +} + /*++ * @name CsrAllocateProcess * @implemented NT4 @@ -49,8 +127,9 @@ CsrAllocateProcess(VOID) CsrProcess = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, TotalSize); if (!CsrProcess) return NULL; - /* Handle the Sequence Number */ + /* Handle the Sequence Number and protect against overflow */ CsrProcess->SequenceNumber = CsrProcessSequenceCount++; + if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5; /* Increase the reference count */ CsrProcess->ReferenceCount++; @@ -66,7 +145,7 @@ CsrAllocateProcess(VOID) * @name CsrServerInitialization * @implemented NT4 * - * The CsrInitializeProcesses routine sets up support for CSR Processes + * The CsrInitializeProcessStructure routine sets up support for CSR Processes * and CSR Threads. * * @param None. @@ -79,13 +158,14 @@ CsrAllocateProcess(VOID) *--*/ NTSTATUS NTAPI -CsrInitializeProcesses(VOID) +CsrInitializeProcessStructure(VOID) { NTSTATUS Status; ULONG i; /* Initialize the Lock */ Status = RtlInitializeCriticalSection(&CsrProcessLock); + if (!NT_SUCCESS(Status)) return Status; /* Set up the Root Process */ CsrRootProcess = CsrAllocateProcess(); @@ -100,8 +180,7 @@ CsrInitializeProcesses(VOID) for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]); /* Initialize the Wait Lock */ - Status = RtlInitializeCriticalSection(&CsrWaitListsLock); - return Status; + return RtlInitializeCriticalSection(&CsrWaitListsLock); } /*++ @@ -155,6 +234,7 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, { PCSR_SERVER_DLL ServerDll; ULONG i; + ASSERT(ProcessStructureListLocked()); /* Set the parent */ CsrProcess->Parent = Parent; @@ -194,15 +274,41 @@ VOID NTAPI CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess) { + LONG LockCount; + /* Decrease reference count */ - if (!(--CsrProcess->ReferenceCount)) + LockCount = --CsrProcess->ReferenceCount; + ASSERT(LockCount >= 0); + if (!LockCount) { /* Call the generic cleanup code */ - CsrAcquireProcessLock(); CsrProcessRefcountZero(CsrProcess); + CsrAcquireProcessLock(); } } +/*++ + * @name CsrLockedReferenceProcess + * + * The CsrLockedReferenceProcess refences a CSR Process while the + * Process Lock is already being held. + * + * @param CsrProcess + * Pointer to the CSR Process to be referenced. + * + * @return None. + * + * @remarks This routine will return with the Process Lock held. + * + *--*/ +VOID +NTAPI +CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess) +{ + /* Increment the reference count */ + ++CsrProcess->ReferenceCount; +} + /*++ * @name CsrRemoveProcess * @@ -211,7 +317,7 @@ CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess) * of this removal. * * @param CsrProcess - * Pointer to the CSR Process to remove. + * Pointer to the CSR Process to remove. * * @return None. * @@ -224,6 +330,7 @@ CsrRemoveProcess(IN PCSR_PROCESS CsrProcess) { PCSR_SERVER_DLL ServerDll; ULONG i; + ASSERT(ProcessStructureListLocked()); /* Remove us from the Process List */ RemoveEntryList(&CsrProcess->ListLink); @@ -279,7 +386,7 @@ CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess) } /* Close the Client Port if there is one */ - if (CsrProcess->ClientPort ) NtClose(CsrProcess->ClientPort); + if (CsrProcess->ClientPort) NtClose(CsrProcess->ClientPort); /* Close the process handle */ NtClose(CsrProcess->ProcessHandle); @@ -289,9 +396,9 @@ CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess) } /*++ - * @name CsrSetToNormalPriority + * @name CsrpSetToNormalPriority * - * The CsrSetToNormalPriority routine sets the current NT Process' + * The CsrpSetToNormalPriority routine sets the current NT Process' * priority to the normal priority for CSR Processes. * * @param None. @@ -304,7 +411,7 @@ CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess) *--*/ VOID NTAPI -CsrSetToNormalPriority(VOID) +CsrpSetToNormalPriority(VOID) { KPRIORITY BasePriority = (8 + 1) + 4; @@ -316,9 +423,9 @@ CsrSetToNormalPriority(VOID) } /*++ - * @name CsrSetToShutdownPriority + * @name CsrpSetToShutdownPriority * - * The CsrSetToShutdownPriority routine sets the current NT Process' + * The CsrpSetToShutdownPriority routine sets the current NT Process' * priority to the boosted priority for CSR Processes doing shutdown. * Additonally, it acquires the Shutdown Privilege required for shutdown. * @@ -332,7 +439,7 @@ CsrSetToNormalPriority(VOID) *--*/ VOID NTAPI -CsrSetToShutdownPriority(VOID) +CsrpSetToShutdownPriority(VOID) { KPRIORITY SetBasePriority = (8 + 1) + 6; BOOLEAN Old; @@ -367,24 +474,20 @@ CsrSetToShutdownPriority(VOID) *--*/ PCSR_PROCESS NTAPI -FindProcessForShutdown(PLUID CallerLuid) +FindProcessForShutdown(IN PLUID CallerLuid) { - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY NextEntry; LUID ProcessLuid; NTSTATUS Status; LUID SystemLuid = SYSTEM_LUID; PCSR_PROCESS CsrProcess; PCSR_THREAD CsrThread; - BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE; PCSR_PROCESS ReturnCsrProcess = NULL; ULONG Level = 0; /* Set the List Pointers */ - ListHead = &CsrRootProcess->ListLink; - NextEntry = ListHead->Flink; - - /* Start looping */ - while (NextEntry != ListHead) + NextEntry = CsrRootProcess->ListLink.Flink; + while (NextEntry != &CsrRootProcess->ListLink) { /* Get the process */ CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); @@ -422,19 +525,19 @@ FindProcessForShutdown(PLUID CallerLuid) } /* Check if this is the System LUID */ - if ((IsSystemLuid = RtlEqualLuid(&ProcessLuid, &SystemLuid))) + if (RtlEqualLuid(&ProcessLuid, &SystemLuid)) { /* Mark this process */ CsrProcess->ShutdownFlags |= CsrShutdownSystem; } - else if (!(IsOurLuid = RtlEqualLuid(&ProcessLuid, CallerLuid))) + else if (!RtlEqualLuid(&ProcessLuid, CallerLuid)) { /* Our LUID doesn't match with the caller's */ CsrProcess->ShutdownFlags |= CsrShutdownOther; } /* Check if we're past the previous level */ - if (CsrProcess->ShutdownLevel > Level) + if ((CsrProcess->ShutdownLevel > Level) || !(ReturnCsrProcess)) { /* Update the level */ Level = CsrProcess->ShutdownLevel; @@ -468,7 +571,7 @@ FindProcessForShutdown(PLUID CallerLuid) * * @param Arguments * Description of the parameter. Wrapped to more lines on ~70th - * column. + * column. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL * othwerwise. @@ -509,19 +612,16 @@ CsrCreateProcess(IN HANDLE hProcess, } /* Allocate a new Process Object */ - if (!(CsrProcess = CsrAllocateProcess())) + CsrProcess = CsrAllocateProcess(); + if (!CsrProcess) { /* Couldn't allocate Process */ CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } - /* Setup Process Data */ - CsrProcess->ClientId = *ClientId; - CsrProcess->ProcessHandle = hProcess; - CsrProcess->ShutdownLevel = 0x280; - /* Inherit the Process Data */ + CurrentProcess = CurrentThread->Process; ProcessData = &CurrentProcess->ServerData[CSR_SERVER_DLL_MAX]; for (i = 0; i < CSR_SERVER_DLL_MAX; i++) { @@ -540,7 +640,7 @@ CsrCreateProcess(IN HANDLE hProcess, ProcessData = (PVOID)((ULONG_PTR)ProcessData + CsrLoadedServerDll[i]->SizeOfProcessData); } - else + else { /* No data for this Server */ CsrProcess->ServerData[i] = NULL; @@ -575,13 +675,13 @@ CsrCreateProcess(IN HANDLE hProcess, } /* Check if this is a console process */ - if(Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp; + if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp; /* Mask out non-debug flags */ - Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup); + Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags); /* Check if every process will be debugged */ - if (!Flags && CurrentProcess->DebugFlags & CsrDebugProcessChildren) + if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren)) { /* Pass it on to the current process */ CsrProcess->DebugFlags = CsrDebugProcessChildren; @@ -589,13 +689,13 @@ CsrCreateProcess(IN HANDLE hProcess, } /* Check if Debugging was used on this process */ - if (Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) + if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid)) { /* Save the debug flag used */ CsrProcess->DebugFlags = Flags; /* Save the CID */ - if (DebugCid) CsrProcess->DebugCid = *DebugCid; + CsrProcess->DebugCid = *DebugCid; } /* Check if we debugging is enabled */ @@ -606,6 +706,7 @@ CsrCreateProcess(IN HANDLE hProcess, ProcessDebugPort, &CsrApiPort, sizeof(HANDLE)); + ASSERT(NT_SUCCESS(Status)); if (!NT_SUCCESS(Status)) { /* Failed */ @@ -621,10 +722,17 @@ CsrCreateProcess(IN HANDLE hProcess, (PVOID)&KernelTimes, sizeof(KernelTimes), NULL); + if (!NT_SUCCESS(Status)) + { + /* Failed */ + CsrDeallocateProcess(CsrProcess); + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } /* Allocate a CSR Thread Structure */ CsrThread = CsrAllocateThread(CsrProcess); - if (CsrThread == NULL) + if (!CsrThread) { /* Failed */ CsrDeallocateProcess(CsrProcess); @@ -636,6 +744,7 @@ CsrCreateProcess(IN HANDLE hProcess, CsrThread->CreateTime = KernelTimes.CreateTime; CsrThread->ClientId = *ClientId; CsrThread->ThreadHandle = hThread; + ProtectHandle(hThread); CsrThread->Flags = 0; /* Insert the Thread into the Process */ @@ -645,6 +754,11 @@ CsrCreateProcess(IN HANDLE hProcess, CsrReferenceNtSession(NtSession); CsrProcess->NtSession = NtSession; + /* Setup Process Data */ + CsrProcess->ClientId = *ClientId; + CsrProcess->ProcessHandle = hProcess; + CsrProcess->ShutdownLevel = 0x280; + /* Set the Priority to Background */ CsrSetBackgroundPriority(CsrProcess); @@ -664,7 +778,7 @@ CsrCreateProcess(IN HANDLE hProcess, * exported only for compatibility with older CSR Server DLLs. * * @param CsrProcess - * Deprecated. + * Deprecated. * * @return Deprecated * @@ -673,7 +787,7 @@ CsrCreateProcess(IN HANDLE hProcess, *--*/ NTSTATUS NTAPI -CsrDebugProcess(PCSR_PROCESS CsrProcess) +CsrDebugProcess(IN PCSR_PROCESS CsrProcess) { /* CSR does not handle debugging anymore */ DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess); @@ -688,7 +802,7 @@ CsrDebugProcess(PCSR_PROCESS CsrProcess) * exported only for compatibility with older CSR Server DLLs. * * @param CsrProcess - * Deprecated. + * Deprecated. * * @return Deprecated * @@ -697,7 +811,7 @@ CsrDebugProcess(PCSR_PROCESS CsrProcess) *--*/ NTSTATUS NTAPI -CsrDebugProcessStop(PCSR_PROCESS CsrProcess) +CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess) { /* CSR does not handle debugging anymore */ DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess); @@ -721,13 +835,17 @@ CsrDebugProcessStop(PCSR_PROCESS CsrProcess) *--*/ VOID NTAPI -CsrDereferenceProcess(PCSR_PROCESS CsrProcess) +CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess) { + LONG LockCount; + /* Acquire process lock */ CsrAcquireProcessLock(); /* Decrease reference count */ - if (!(--CsrProcess->ReferenceCount)) + LockCount = --CsrProcess->ReferenceCount; + ASSERT(LockCount >= 0); + if (!LockCount) { /* Call the generic cleanup code */ CsrProcessRefcountZero(CsrProcess); @@ -743,12 +861,12 @@ CsrDereferenceProcess(PCSR_PROCESS CsrProcess) * @name CsrDestroyProcess * @implemented NT4 * - * The CsrDestroyProcess routine destroys the CSR Process corresponding to + * The CsrDestroyProcess routine destroys the CSR Process corresponding to * a given Client ID. * * @param Cid * Pointer to the Client ID Structure corresponding to the CSR - * Process which is about to be destroyed. + * Process which is about to be destroyed. * * @param ExitStatus * Unused. @@ -767,17 +885,16 @@ CsrDestroyProcess(IN PCLIENT_ID Cid, PCSR_THREAD CsrThread; PCSR_PROCESS CsrProcess; CLIENT_ID ClientId = *Cid; - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY NextEntry; /* Acquire lock */ CsrAcquireProcessLock(); /* Find the thread */ - CsrThread = CsrLocateThreadByClientId(&CsrProcess, - &ClientId); + CsrThread = CsrLocateThreadByClientId(&CsrProcess, &ClientId); /* Make sure we got one back, and that it's not already gone */ - if (!CsrThread || CsrProcess->Flags & CsrProcessTerminating) + if (!(CsrThread) || (CsrProcess->Flags & CsrProcessTerminating)) { /* Release the lock and return failure */ CsrReleaseProcessLock(); @@ -788,20 +905,18 @@ CsrDestroyProcess(IN PCLIENT_ID Cid, CsrProcess->Flags |= CsrProcessTerminating; /* Get the List Pointers */ - ListHead = &CsrProcess->ThreadList; - NextEntry = ListHead->Flink; - - /* Loop the list */ - while (NextEntry != ListHead) + NextEntry = CsrProcess->ThreadList.Flink; + while (NextEntry != &CsrProcess->ThreadList) { /* Get the current thread entry */ CsrThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); - /* Move to the next entry */ - NextEntry = NextEntry->Flink; - /* Make sure the thread isn't already dead */ - if (CsrThread->Flags & CsrThreadTerminated) continue; + if (CsrThread->Flags & CsrThreadTerminated) + { + NextEntry = NextEntry->Flink; + continue; + } /* Set the Terminated flag */ CsrThread->Flags |= CsrThreadTerminated; @@ -826,6 +941,7 @@ CsrDestroyProcess(IN PCLIENT_ID Cid, /* Dereference the thread */ CsrLockedDereferenceThread(CsrThread); + NextEntry = CsrProcess->ThreadList.Flink; } /* Release the Process Lock and return success */ @@ -843,7 +959,7 @@ CsrDestroyProcess(IN PCLIENT_ID Cid, * Optional handle to the process whose LUID should be returned. * * @param Luid - * Pointer to a LUID Pointer which will receive the CSR Process' LUID + * Pointer to a LUID Pointer which will receive the CSR Process' LUID * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL * othwerwise. @@ -891,11 +1007,7 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL, Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken); - if (!NT_SUCCESS(Status)) - { - /* Still no token, return the error */ - return Status; - } + if (!NT_SUCCESS(Status)) return Status; } /* Now get the size we'll need for the Token Information */ @@ -906,7 +1018,8 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL, &Length); /* Allocate memory for the Token Info */ - if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length))) + TokenStats = RtlAllocateHeap(CsrHeap, 0, Length); + if (!TokenStats) { /* Fail and close the token */ NtClose(hToken); @@ -923,12 +1036,8 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL, /* Close the handle */ NtClose(hToken); - /* Check for success */ - if (NT_SUCCESS(Status)) - { - /* Return the LUID */ - *Luid = TokenStats->AuthenticationId; - } + /* Check for success to return the LUID */ + if (NT_SUCCESS(Status)) *Luid = TokenStats->AuthenticationId; /* Free the query information */ RtlFreeHeap(CsrHeap, 0, TokenStats); @@ -961,51 +1070,45 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL, NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, - OUT PCSR_PROCESS *CsrProcess OPTIONAL) + OUT PCSR_PROCESS *CsrProcess) { - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY NextEntry; PCSR_PROCESS CurrentProcess = NULL; NTSTATUS Status = STATUS_UNSUCCESSFUL; /* Acquire the lock */ CsrAcquireProcessLock(); - /* Setup the List Pointers */ - ListHead = &CsrRootProcess->ListLink; - NextEntry = ListHead; + /* Assume failure */ + ASSERT(CsrProcess != NULL); + *CsrProcess = NULL; - /* Start Loop */ - while (NextEntry != ListHead) + /* Setup the List Pointers */ + NextEntry = CsrRootProcess->ListLink.Flink; + while (NextEntry != &CsrRootProcess->ListLink) { /* Get the Process */ CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); /* Check for PID Match */ - if (CurrentProcess->ClientId.UniqueProcess == Pid) - { - /* Get out of here with success */ - Status = STATUS_SUCCESS; - break; - } + if (CurrentProcess->ClientId.UniqueProcess == Pid) break; /* Next entry */ NextEntry = NextEntry->Flink; } - /* Did the loop find something? */ - if (NT_SUCCESS(Status)) - { - /* Lock the found process */ - CurrentProcess->ReferenceCount++; - } - else + /* Check if we didn't find it in the list */ + if (NextEntry == &CsrRootProcess->ListLink) { /* Nothing found, release the lock */ CsrReleaseProcessLock(); + return Status; } - /* Return the status and process */ - if (CsrProcess) *CsrProcess = CurrentProcess; + /* Lock the found process and return it */ + Status = STATUS_SUCCESS; + CurrentProcess->ReferenceCount++; + *CsrProcess = CurrentProcess; return Status; } @@ -1093,16 +1196,16 @@ CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess) *--*/ NTSTATUS NTAPI -CsrShutdownProcesses(PLUID CallerLuid, - ULONG Flags) +CsrShutdownProcesses(IN PLUID CallerLuid, + IN ULONG Flags) { - PLIST_ENTRY ListHead, NextEntry; - PCSR_PROCESS CsrProcess = NULL; - NTSTATUS Status = STATUS_UNSUCCESSFUL; - BOOLEAN FirstTry = TRUE; - ULONG i = 0; - PCSR_SERVER_DLL ServerDll = NULL; - ULONG Result = 0; + PLIST_ENTRY NextEntry; + PCSR_PROCESS CsrProcess; + NTSTATUS Status; + BOOLEAN FirstTry; + ULONG i; + PCSR_SERVER_DLL ServerDll; + ULONG Result; /* Acquire process lock */ CsrAcquireProcessLock(); @@ -1111,11 +1214,8 @@ CsrShutdownProcesses(PLUID CallerLuid, CsrRootProcess->ShutdownFlags |= CsrShutdownSystem; /* Get the list pointers */ - ListHead = &CsrRootProcess->ListLink; - NextEntry = ListHead->Flink; - - /* Start the loop */ - while (NextEntry != ListHead) + NextEntry = CsrRootProcess->ListLink.Flink; + while (NextEntry != &CsrRootProcess->ListLink) { /* Get the Process */ CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); @@ -1129,73 +1229,81 @@ CsrShutdownProcesses(PLUID CallerLuid, } /* Set shudown Priority */ - CsrSetToShutdownPriority(); + CsrpSetToShutdownPriority(); /* Start looping */ while (TRUE) { /* Find the next process to shutdown */ - if (!(CsrProcess = FindProcessForShutdown(CallerLuid))) - { - /* Done, quit */ - CsrReleaseProcessLock(); - Status = STATUS_SUCCESS; - goto Quickie; - } + CsrProcess = FindProcessForShutdown(CallerLuid); + if (!CsrProcess) break; /* Increase reference to process */ CsrProcess->ReferenceCount++; -LoopAgain: - /* Loop all the servers */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) + FirstTry = TRUE; + while (TRUE) { - /* Get the current server */ - ServerDll = CsrLoadedServerDll[i]; - if (ServerDll && ServerDll->ShutdownProcessCallback) + /* Loop all the servers */ + for (i = 0; i < CSR_SERVER_DLL_MAX; i++) { - /* Release the lock, make the callback, and acquire it back */ - CsrReleaseProcessLock(); - Result = (*ServerDll->ShutdownProcessCallback)(CsrProcess, - Flags, - FirstTry); - CsrAcquireProcessLock(); - - /* Check the result */ - if (Result == CsrShutdownCsrProcess) + /* Get the current server */ + ServerDll = CsrLoadedServerDll[i]; + if ((ServerDll) && (ServerDll->ShutdownProcessCallback)) { - /* The callback unlocked the process */ - break; - } - else if (Result == CsrShutdownNonCsrProcess) - { - /* A non-CSR process, the callback didn't touch it */ - continue; - } - else if (Result == CsrShutdownCancelled) - { - /* Shutdown was cancelled, unlock and exit */ + /* Release the lock, make the callback, and acquire it back */ CsrReleaseProcessLock(); - Status = STATUS_CANCELLED; - goto Quickie; + Result = (*ServerDll->ShutdownProcessCallback)(CsrProcess, + Flags, + FirstTry); + CsrAcquireProcessLock(); + + /* Check the result */ + if (Result == CsrShutdownCsrProcess) + { + /* The callback unlocked the process */ + break; + } + else if (Result == CsrShutdownCancelled) + { + /* Check if this was a forced shutdown */ + if (Flags & EWX_FORCE) + { + DPRINT1("Process %x cancelled forced shutdown (Dll = %d)\n", + CsrProcess->ClientId.UniqueProcess, i); + DbgBreakPoint(); + } + + /* Shutdown was cancelled, unlock and exit */ + CsrReleaseProcessLock(); + Status = STATUS_CANCELLED; + goto Quickie; + } } } - } - /* No matches during the first try, so loop again */ - if (FirstTry && Result == CsrShutdownNonCsrProcess) - { - FirstTry = FALSE; - goto LoopAgain; + /* No matches during the first try, so loop again */ + if ((FirstTry) && (Result == CsrShutdownNonCsrProcess)) + { + FirstTry = FALSE; + continue; + } + + /* Second try, break out */ + break; } /* We've reached the final loop here, so dereference */ if (i == CSR_SERVER_DLL_MAX) CsrLockedDereferenceProcess(CsrProcess); } + /* Success path */ + CsrReleaseProcessLock(); + Status = STATUS_SUCCESS; + Quickie: /* Return to normal priority */ - CsrSetToNormalPriority(); + CsrpSetToNormalPriority(); return Status; } @@ -1206,7 +1314,7 @@ Quickie: * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation. * * @param CsrProcess - * Pointer to a previously locked CSR Process. + * Pointer to a previously locked CSR Process. * * @return STATUS_SUCCESS. * @@ -1215,7 +1323,7 @@ Quickie: *--*/ NTSTATUS NTAPI -CsrUnlockProcess(PCSR_PROCESS CsrProcess) +CsrUnlockProcess(IN PCSR_PROCESS CsrProcess) { /* Dereference the process */ CsrLockedDereferenceProcess(CsrProcess); diff --git a/reactos/subsystems/csr/csrsrv/server.c b/reactos/subsystems/csr/csrsrv/server.c index 2faad8f6264..91699cd0d02 100644 --- a/reactos/subsystems/csr/csrsrv/server.c +++ b/reactos/subsystems/csr/csrsrv/server.c @@ -78,40 +78,57 @@ CsrLoadServerDll(IN PCHAR DllString, { NTSTATUS Status; ANSI_STRING DllName; - UNICODE_STRING TempString; + UNICODE_STRING TempString, ErrorString; + ULONG_PTR Parameters[2]; HANDLE hServerDll = NULL; ULONG Size; PCSR_SERVER_DLL ServerDll; STRING EntryPointString; PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure; + ULONG Response; /* Check if it's beyond the maximum we support */ - if (ServerId >= CSR_SERVER_DLL_MAX) return(STATUS_TOO_MANY_NAMES); + if (ServerId >= CSR_SERVER_DLL_MAX) return STATUS_TOO_MANY_NAMES; /* Check if it's already been loaded */ - if (CsrLoadedServerDll[ServerId]) return(STATUS_INVALID_PARAMETER); + if (CsrLoadedServerDll[ServerId]) return STATUS_INVALID_PARAMETER; /* Convert the name to Unicode */ + ASSERT(DllString != NULL); RtlInitAnsiString(&DllName, DllString); Status = RtlAnsiStringToUnicodeString(&TempString, &DllName, TRUE); + if (!NT_SUCCESS(Status)) return Status; /* If we are loading ourselves, don't actually load us */ if (ServerId != CSR_SRV_SERVER) { /* Load the DLL */ Status = LdrLoadDll(NULL, 0, &TempString, &hServerDll); + if (!NT_SUCCESS(Status)) + { + /* Setup error parameters */ + Parameters[0] = (ULONG_PTR)&TempString; + Parameters[1] = (ULONG_PTR)&ErrorString; + RtlInitUnicodeString(&ErrorString, L"Default Load Path"); + + /* Send a hard error */ + NtRaiseHardError(Status, + 2, + 3, + Parameters, + OptionOk, + &Response); + } /* Get rid of the string */ RtlFreeUnicodeString(&TempString); - if (!NT_SUCCESS(Status)) - { - return Status; - } + if (!NT_SUCCESS(Status)) return Status; } /* Allocate a CSR DLL Object */ Size = sizeof(CSR_SERVER_DLL) + DllName.MaximumLength; - if (!(ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size))) + ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size); + if (!ServerDll) { if (hServerDll) LdrUnloadDll(hServerDll); return STATUS_NO_MEMORY; @@ -135,7 +152,7 @@ CsrLoadServerDll(IN PCHAR DllString, if (hServerDll) { /* Initialize a string for the entrypoint, or use the default */ - RtlInitAnsiString(&EntryPointString, + RtlInitAnsiString(&EntryPointString, !(EntryPoint) ? "ServerDllInitialization" : EntryPoint); @@ -255,6 +272,7 @@ CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage, NTSTATUS Status; PCSR_CLIENT_CONNECT ClientConnect; PCSR_SERVER_DLL ServerDll; + PCSR_PROCESS CurrentProcess = ((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process; /* Load the Message, set default reply */ ClientConnect = (PCSR_CLIENT_CONNECT)&ApiMessage->CsrClientConnect; @@ -287,7 +305,7 @@ CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage, if (ServerDll->ConnectCallback) { /* Call the callback */ - Status = (ServerDll->ConnectCallback)(((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process, + Status = (ServerDll->ConnectCallback)(CurrentProcess, ClientConnect->ConnectionInfo, &ClientConnect->ConnectionInfoSize); } @@ -328,12 +346,15 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue) ULONG ViewSize = 0; PPEB Peb = NtCurrentPeb(); + /* If there's no parameter, fail */ + if (ParameterValue) return STATUS_INVALID_PARAMETER; + /* Find the first comma, and null terminate */ while (*SizeValue) { if (*SizeValue == ',') { - *SizeValue++ = '\0'; + *SizeValue++ = ANSI_NULL; break; } else @@ -343,12 +364,10 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue) } /* Make sure it's valid */ - if (!*SizeValue) return(STATUS_INVALID_PARAMETER); + if (!*SizeValue) return STATUS_INVALID_PARAMETER; /* Convert it to an integer */ - Status = RtlCharToInteger(SizeValue, - 0, - &Size); + Status = RtlCharToInteger(SizeValue, 0, &Size); if (!NT_SUCCESS(Status)) return Status; /* Multiply by 1024 entries and round to page size */ @@ -377,7 +396,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue) ViewUnmap, MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE); - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { /* Fail */ NtClose(CsrSrvSharedSection); @@ -390,7 +409,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue) CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase; /* Create the heap */ - if (!(RtlCreateHeap(HEAP_ZERO_MEMORY, + if (!(RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_CLASS_7, CsrSrvSharedSectionHeap, CsrSrvSharedSectionSize, PAGE_SIZE, @@ -398,8 +417,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue) 0))) { /* Failure, unmap section and return */ - NtUnmapViewOfSection(NtCurrentProcess(), - CsrSrvSharedSectionBase); + NtUnmapViewOfSection(NtCurrentProcess(), CsrSrvSharedSectionBase); NtClose(CsrSrvSharedSection); return STATUS_NO_MEMORY; } @@ -409,6 +427,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue) 0, CSR_SERVER_DLL_MAX * sizeof(PVOID)); + if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY; /* Write the values to the PEB */ Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase; @@ -621,7 +640,7 @@ CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo) (DebuggerInfo.KernelDebuggerEnabled)) { /* Call the Unhandled Exception Filter */ - if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) != + if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) != EXCEPTION_CONTINUE_EXECUTION) { /* We're going to raise an error. Get Shutdown Privilege first */ @@ -656,7 +675,7 @@ CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo) OptionShutdownSystem, &Response); } - + /* Just terminate us */ NtTerminateProcess(NtCurrentProcess(), ExceptionInfo->ExceptionRecord->ExceptionCode); diff --git a/reactos/subsystems/csr/csrsrv/session.c b/reactos/subsystems/csr/csrsrv/session.c index bbbe3a09c5c..2ec08a66a4f 100644 --- a/reactos/subsystems/csr/csrsrv/session.c +++ b/reactos/subsystems/csr/csrsrv/session.c @@ -14,6 +14,7 @@ #include /* DATA **********************************************************************/ + RTL_CRITICAL_SECTION CsrNtSessionLock; LIST_ENTRY CsrNtSessionList; HANDLE CsrSmApiPort; @@ -39,31 +40,28 @@ PCHAR CsrServerSbApiName[5] = /* PRIVATE FUNCTIONS *********************************************************/ /*++ - * @name CsrInitializeNtSessions + * @name CsrInitializeNtSessionList * - * The CsrInitializeNtSessions routine sets up support for CSR Sessions. + * The CsrInitializeNtSessionList routine sets up support for CSR Sessions. * * @param None * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. + * @return None * * @remarks None. * *--*/ NTSTATUS NTAPI -CsrInitializeNtSessions(VOID) +CsrInitializeNtSessionList(VOID) { - NTSTATUS Status; DPRINT("CSRSRV: %s called\n", __FUNCTION__); /* Initialize the Session List */ InitializeListHead(&CsrNtSessionList); /* Initialize the Session Lock */ - Status = RtlInitializeCriticalSection(&CsrNtSessionLock); - return Status; + return RtlInitializeCriticalSection(&CsrNtSessionLock); } /*++ @@ -72,7 +70,7 @@ CsrInitializeNtSessions(VOID) * The CsrAllocateNtSession routine allocates a new CSR NT Session. * * @param SessionId - * Session ID of the CSR NT Session to allocate. + * Session ID of the CSR NT Session to allocate. * * @return Pointer to the newly allocated CSR NT Session. * @@ -81,26 +79,27 @@ CsrInitializeNtSessions(VOID) *--*/ PCSR_NT_SESSION NTAPI -CsrAllocateNtSession(ULONG SessionId) +CsrAllocateNtSession(IN ULONG SessionId) { PCSR_NT_SESSION NtSession; /* Allocate an NT Session Object */ - NtSession = RtlAllocateHeap(CsrHeap, - 0, - sizeof(CSR_NT_SESSION)); - - /* Setup the Session Object */ + NtSession = RtlAllocateHeap(CsrHeap, 0, sizeof(CSR_NT_SESSION)); if (NtSession) { + /* Setup the Session Object */ NtSession->SessionId = SessionId; NtSession->ReferenceCount = 1; /* Insert it into the Session List */ CsrAcquireNtSessionLock(); - InsertHeadList(&CsrNtSessionList, &NtSession->SessionList); + InsertHeadList(&CsrNtSessionList, &NtSession->SessionLink); CsrReleaseNtSessionLock(); } + else + { + ASSERT(NtSession != NULL); + } /* Return the Session (or NULL) */ return NtSession; @@ -112,7 +111,7 @@ CsrAllocateNtSession(ULONG SessionId) * The CsrReferenceNtSession increases the reference count of a CSR NT Session. * * @param Session - * Pointer to the CSR NT Session to reference. + * Pointer to the CSR NT Session to reference. * * @return None. * @@ -121,11 +120,16 @@ CsrAllocateNtSession(ULONG SessionId) *--*/ VOID NTAPI -CsrReferenceNtSession(PCSR_NT_SESSION Session) +CsrReferenceNtSession(IN PCSR_NT_SESSION Session) { /* Acquire the lock */ CsrAcquireNtSessionLock(); + /* Sanity checks */ + ASSERT(!IsListEmpty(&Session->SessionLink)); + ASSERT(Session->SessionId != 0); + ASSERT(Session->ReferenceCount != 0); + /* Increase the reference count */ Session->ReferenceCount++; @@ -140,8 +144,8 @@ CsrReferenceNtSession(PCSR_NT_SESSION Session) * CSR NT Session. * * @param Session - * Pointer to the CSR NT Session to reference. - * + * Pointer to the CSR NT Session to reference. + * * @param ExitStatus * If this is the last reference to the session, this argument * specifies the exit status. @@ -154,17 +158,22 @@ CsrReferenceNtSession(PCSR_NT_SESSION Session) *--*/ VOID NTAPI -CsrDereferenceNtSession(PCSR_NT_SESSION Session, - NTSTATUS ExitStatus) +CsrDereferenceNtSession(IN PCSR_NT_SESSION Session, + IN NTSTATUS ExitStatus) { /* Acquire the lock */ CsrAcquireNtSessionLock(); + /* Sanity checks */ + ASSERT(!IsListEmpty(&Session->SessionLink)); + ASSERT(Session->SessionId != 0); + ASSERT(Session->ReferenceCount != 0); + /* Dereference the Session Object */ if (!(--Session->ReferenceCount)) { /* Remove it from the list */ - RemoveEntryList(&Session->SessionList); + RemoveEntryList(&Session->SessionLink); /* Release the lock */ CsrReleaseNtSessionLock(); @@ -202,9 +211,9 @@ CsrDereferenceNtSession(PCSR_NT_SESSION Session, *--*/ BOOLEAN NTAPI -CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage) +CsrSbCreateSession(IN PSB_API_MSG ApiMessage) { - PSB_CREATE_SESSION CreateSession = &ApiMessage->SbCreateSession; + PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession; HANDLE hProcess, hThread; PCSR_PROCESS CsrProcess; NTSTATUS Status; @@ -221,18 +230,15 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage) CsrAcquireProcessLock(); /* Allocate a new process */ - if (!(CsrProcess = CsrAllocateProcess())) + CsrProcess = CsrAllocateProcess(); + if (!CsrProcess) { /* Fail */ - ApiMessage->Status = STATUS_NO_MEMORY; + ApiMessage->ReturnValue = STATUS_NO_MEMORY; CsrReleaseProcessLock(); return TRUE; } - /* Setup Process Data */ - CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId; - CsrProcess->ProcessHandle = hProcess; - /* Set the exception port */ Status = NtSetInformationProcess(hProcess, ProcessExceptionPort, @@ -264,15 +270,17 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage) CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); + /* Strange as it seems, NTSTATUSes are actually returned */ return (BOOLEAN)Status; } /* Allocate a new Thread */ - if (!(CsrThread = CsrAllocateThread(CsrProcess))) + CsrThread = CsrAllocateThread(CsrProcess); + if (!CsrThread) { /* Fail the request */ CsrDeallocateProcess(CsrProcess); - ApiMessage->Status = STATUS_NO_MEMORY; + ApiMessage->ReturnValue = STATUS_NO_MEMORY; CsrReleaseProcessLock(); return TRUE; } @@ -281,12 +289,15 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage) CsrThread->CreateTime = KernelTimes.CreateTime; CsrThread->ClientId = CreateSession->ProcessInfo.ClientId; CsrThread->ThreadHandle = hThread; + ProtectHandle(hThread); CsrThread->Flags = 0; /* Insert it into the Process List */ CsrInsertThread(CsrProcess, CsrThread); - /* Allocate a new Session */ + /* Setup Process Data */ + CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId; + CsrProcess->ProcessHandle = hProcess; CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId); /* Set the Process Priority */ @@ -319,7 +330,7 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage) CsrInsertProcess(NULL, NULL, CsrProcess); /* Activate the Thread */ - ApiMessage->Status = NtResumeThread(hThread, NULL); + ApiMessage->ReturnValue = NtResumeThread(hThread, NULL); /* Release lock and return */ CsrReleaseProcessLock(); @@ -342,10 +353,55 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage) *--*/ BOOLEAN NTAPI -CsrSbForeignSessionComplete(IN PSB_API_MESSAGE ApiMessage) +CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage) { /* Deprecated/Unimplemented in NT */ - ApiMessage->Status = STATUS_NOT_IMPLEMENTED; + ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED; return TRUE; } + +/*++ + * @name CsrSbTerminateSession + * + * The CsrSbTerminateSession API is called by the Session Manager + * whenever a foreign session should be destroyed. + * + * @param ApiMessage + * Pointer to the Session Manager API Message. + * + * @return TRUE in case of success, FALSE othwerwise. + * + * @remarks The CsrSbTerminateSession API is not yet implemented. + * + *--*/ +BOOLEAN +NTAPI +CsrSbTerminateSession(IN PSB_API_MSG ApiMessage) +{ + ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED; + return TRUE; +} + +/*++ + * @name CsrSbCreateProcess + * + * The CsrSbCreateProcess API is called by the Session Manager + * whenever a foreign session is created and a new process should be started. + * + * @param ApiMessage + * Pointer to the Session Manager API Message. + * + * @return TRUE in case of success, FALSE othwerwise. + * + * @remarks The CsrSbCreateProcess API is not yet implemented. + * + *--*/ +BOOLEAN +NTAPI +CsrSbCreateProcess(IN PSB_API_MSG ApiMessage) +{ + ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED; + return TRUE; +} + /* EOF */ diff --git a/reactos/subsystems/csr/csrsrv/srv.h b/reactos/subsystems/csr/csrsrv/srv.h index 8c55942630f..3f59a486d28 100644 --- a/reactos/subsystems/csr/csrsrv/srv.h +++ b/reactos/subsystems/csr/csrsrv/srv.h @@ -10,6 +10,7 @@ /* CSR Header */ #include +#include /* PSEH for SEH Support */ #include @@ -38,6 +39,9 @@ #define CsrHashThread(t) \ (HandleToUlong(t)&(256 - 1)) + +#define ProcessStructureListLocked() \ + (CsrProcessLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread) #define SM_REG_KEY \ L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager" @@ -72,10 +76,18 @@ extern SYSTEM_BASIC_INFORMATION CsrNtSysInfo; extern UNICODE_STRING CsrDirectoryName; extern HANDLE CsrObjectDirectory; extern PSB_API_ROUTINE CsrServerSbApiDispatch[5]; +extern ULONG CsrDebug; /* FUNCTIONS *****************************************************************/ /* FIXME: Public APIs should go in the CSR Server Include */ +BOOLEAN +NTAPI +CsrCaptureArguments( + IN PCSR_THREAD CsrThread, + IN PCSR_API_MESSAGE ApiMessage +); + NTSTATUS NTAPI CsrLoadServerDll( @@ -91,6 +103,18 @@ CsrServerInitialization( PCHAR Arguments[] ); +BOOLEAN +NTAPI +UnProtectHandle(IN HANDLE ObjectHandle); + +VOID +NTAPI +CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess); + +VOID +NTAPI +CsrLockedReferenceThread(IN PCSR_THREAD CsrThread); + NTSTATUS NTAPI CsrCreateSessionObjectDirectory(IN ULONG SessionId); @@ -105,11 +129,11 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue); NTSTATUS NTAPI -CsrInitializeNtSessions(VOID); +CsrInitializeNtSessionList(VOID); NTSTATUS NTAPI -CsrInitializeProcesses(VOID); +CsrInitializeProcessStructure(VOID); NTSTATUS NTAPI @@ -121,19 +145,19 @@ CsrSbApiPortInitialize(VOID); BOOLEAN NTAPI -CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage); +CsrSbCreateSession(IN PSB_API_MSG ApiMessage); BOOLEAN NTAPI -CsrSbTerminateSession(IN PSB_API_MESSAGE ApiMessage); +CsrSbTerminateSession(IN PSB_API_MSG ApiMessage); BOOLEAN NTAPI -CsrSbForeignSessionComplete(IN PSB_API_MESSAGE ApiMessage); +CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage); BOOLEAN NTAPI -CsrSbCreateProcess(IN PSB_API_MESSAGE ApiMessage); +CsrSbCreateProcess(IN PSB_API_MSG ApiMessage); PCSR_PROCESS NTAPI @@ -254,6 +278,10 @@ NTSTATUS NTAPI CsrApiRequestThread(IN PVOID Parameter); +BOOLEAN +NTAPI +ProtectHandle(IN HANDLE ObjectHandle); + PCSR_THREAD NTAPI CsrAddStaticServerThread( @@ -275,7 +303,7 @@ CsrLocateThreadInProcess( NTSTATUS NTAPI -CsrSbApiHandleConnectionRequest(IN PSB_API_MESSAGE Message); +CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message); NTSTATUS NTAPI diff --git a/reactos/subsystems/csr/csrsrv/status.h b/reactos/subsystems/csr/csrsrv/status.h index c9ff9aa3aca..e619443abd3 100644 --- a/reactos/subsystems/csr/csrsrv/status.h +++ b/reactos/subsystems/csr/csrsrv/status.h @@ -59,7 +59,7 @@ * CsrMoveSatisfiedWait 753E7909 20 - wait.c - IMPLEMENTED * CsrNotifyWait 753E782F 21 - wait.c - IMPLEMENTED * CsrPopulateDosDevices 753E37A5 22 - init.c - IMPLEMENTED - * CsrQueryApiPort 753E4E42 23 - api.c - UNIMPLEMENTED + * CsrQueryApiPort 753E4E42 23 - api.c - IMPLEMENTED * CsrReferenceThread 753E61E5 24 - thread.c - IMPLEMENTED * CsrRevertToSelf 753E615A 25 - thread.c - IMPLEMENTED * CsrServerInitialization 753E3D75 26 - server.c - IMPLEMENTED @@ -93,7 +93,7 @@ * - SMSS needs to be partly re-written to match some things done here. * Among other things, SmConnectToSm, SmCompleteSession and the other * Sm* Exported APIs have to be properly implemented, as well as the - * callback calling and SM LPC APIs. [NOT DONE] + * callback calling and SM LPC APIs. [DONE!] * * - NTDLL needs to get the Csr* routines properly implemented. [DONE!] * diff --git a/reactos/subsystems/csr/csrsrv/thread.c b/reactos/subsystems/csr/csrsrv/thread.c index ad71435589c..c03f61d82b0 100644 --- a/reactos/subsystems/csr/csrsrv/thread.c +++ b/reactos/subsystems/csr/csrsrv/thread.c @@ -47,7 +47,7 @@ CsrAllocateThread(IN PCSR_PROCESS CsrProcess) /* Allocate the structure */ CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD)); - if (!CsrThread) return(NULL); + if (!CsrThread) return NULL; /* Reference the Thread and Process */ CsrThread->ReferenceCount++; @@ -86,24 +86,24 @@ CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, IN PCLIENT_ID ClientId) { ULONG i; - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY NextEntry; PCSR_THREAD FoundThread; + ASSERT(ProcessStructureListLocked()); /* Hash the Thread */ i = CsrHashThread(ClientId->UniqueThread); - + /* Set the list pointers */ - ListHead = &CsrThreadHashTable[i]; - NextEntry = ListHead->Flink; + NextEntry = CsrThreadHashTable[i].Flink; /* Star the loop */ - while (NextEntry != ListHead) + while (NextEntry != &CsrThreadHashTable[i]) { /* Get the thread */ FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); /* Compare the CID */ - if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread) + if (*(PULONGLONG)&FoundThread->ClientId == *(PULONGLONG)ClientId) { /* Match found, return the process */ *Process = FoundThread->Process; @@ -123,7 +123,7 @@ CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, /*++ * @name CsrLocateThreadInProcess * - * The CsrLocateThreadInProcess routine locates the CSR Thread + * The CsrLocateThreadInProcess routine locates the CSR Thread * corresponding to a Client ID inside a specific CSR Process. * * @param Process @@ -146,18 +146,17 @@ NTAPI CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, IN PCLIENT_ID Cid) { - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY NextEntry; PCSR_THREAD FoundThread = NULL; /* Use the Root Process if none was specified */ if (!CsrProcess) CsrProcess = CsrRootProcess; /* Save the List pointers */ - ListHead = &CsrProcess->ThreadList; - NextEntry = ListHead->Flink; + NextEntry = CsrProcess->ThreadList.Flink; /* Start the Loop */ - while (NextEntry != ListHead) + while (NextEntry != &CsrProcess->ThreadList) { /* Get Thread Entry */ FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); @@ -196,6 +195,7 @@ CsrInsertThread(IN PCSR_PROCESS Process, IN PCSR_THREAD Thread) { ULONG i; + ASSERT(ProcessStructureListLocked()); /* Insert it into the Regular List */ InsertTailList(&Process->ThreadList, &Thread->Link); @@ -230,9 +230,32 @@ NTAPI CsrDeallocateThread(IN PCSR_THREAD CsrThread) { /* Free the process object from the heap */ + ASSERT(CsrThread->WaitBlock == NULL); RtlFreeHeap(CsrHeap, 0, CsrThread); } +/*++ + * @name CsrLockedReferenceThread + * + * The CsrLockedReferenceThread refences a CSR Thread while the + * Process Lock is already being held. + * + * @param CsrThread + * Pointer to the CSR Thread to be referenced. + * + * @return None. + * + * @remarks This routine will return with the Process Lock held. + * + *--*/ +VOID +NTAPI +CsrLockedReferenceThread(IN PCSR_THREAD CsrThread) +{ + /* Increment the reference count */ + ++CsrThread->ReferenceCount; +} + /*++ * @name CsrLockedDereferenceThread * @@ -249,10 +272,14 @@ CsrDeallocateThread(IN PCSR_THREAD CsrThread) *--*/ VOID NTAPI -CsrLockedDereferenceThread(PCSR_THREAD CsrThread) +CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread) { + LONG LockCount; + /* Decrease reference count */ - if (!(--CsrThread->ReferenceCount)) + LockCount = --CsrThread->ReferenceCount; + ASSERT(LockCount >= 0); + if (!LockCount) { /* Call the generic cleanup code */ CsrThreadRefcountZero(CsrThread); @@ -267,7 +294,7 @@ CsrLockedDereferenceThread(PCSR_THREAD CsrThread) * removes the CSR Thread from the the Hash Table and Thread List. * * @param CsrThread - * Pointer to the CSR Thread to remove. + * Pointer to the CSR Thread to remove. * * @return None. * @@ -283,11 +310,13 @@ VOID NTAPI CsrRemoveThread(IN PCSR_THREAD CsrThread) { + ASSERT(ProcessStructureListLocked()); + /* Remove it from the List */ RemoveEntryList(&CsrThread->Link); /* Decreate the thread count of the process */ - CsrThread->Process->ThreadCount--; + --CsrThread->Process->ThreadCount; /* Remove it from the Hash List as well */ if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks); @@ -333,6 +362,7 @@ NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) { PCSR_PROCESS CsrProcess = CsrThread->Process; + NTSTATUS Status; /* Remove this thread */ CsrRemoveThread(CsrThread); @@ -341,8 +371,10 @@ CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) CsrReleaseProcessLock(); /* Close the NT Thread Handle */ - NtClose(CsrThread->ThreadHandle); - + UnProtectHandle(CsrThread->ThreadHandle); + Status = NtClose(CsrThread->ThreadHandle); + ASSERT(NT_SUCCESS(Status)); + /* De-allocate the CSR Thread Object */ CsrDeallocateThread(CsrThread); @@ -388,10 +420,12 @@ CsrAddStaticServerThread(IN HANDLE hThread, CsrAcquireProcessLock(); /* Allocate the Server Thread */ - if ((CsrThread = CsrAllocateThread(CsrRootProcess))) + CsrThread = CsrAllocateThread(CsrRootProcess); + if (CsrThread) { /* Setup the Object */ CsrThread->ThreadHandle = hThread; + ProtectHandle(hThread); CsrThread->ClientId = *ClientId; CsrThread->Flags = ThreadFlags; @@ -401,6 +435,10 @@ CsrAddStaticServerThread(IN HANDLE hThread, /* Increment the thread count */ CsrRootProcess->ThreadCount++; } + else + { + DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread); + } /* Release the Process Lock and return */ CsrReleaseProcessLock(); @@ -420,7 +458,7 @@ CsrAddStaticServerThread(IN HANDLE hThread, * * @param ClientId * Pointer to the Client ID structure of the NT Thread to associate - * with this CSR Thread. + * with this CSR Thread. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL * othwerwise. @@ -444,13 +482,13 @@ CsrCreateRemoteThread(IN HANDLE hThread, /* Get the Thread Create Time */ Status = NtQueryInformationThread(hThread, ThreadTimes, - (PVOID)&KernelTimes, + &KernelTimes, sizeof(KernelTimes), NULL); + if (!NT_SUCCESS(Status)) return Status; /* Lock the Owner Process */ - Status = CsrLockProcessByClientId(&ClientId->UniqueProcess, - &CsrProcess); + Status = CsrLockProcessByClientId(&ClientId->UniqueProcess, &CsrProcess); /* Make sure the thread didn't terminate */ if (KernelTimes.ExitTime.QuadPart) @@ -461,7 +499,8 @@ CsrCreateRemoteThread(IN HANDLE hThread, } /* Allocate a CSR Thread Structure */ - if (!(CsrThread = CsrAllocateThread(CsrProcess))) + CsrThread = CsrAllocateThread(CsrProcess); + if (!CsrThread) { DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__); CsrUnlockProcess(CsrProcess); @@ -483,6 +522,7 @@ CsrCreateRemoteThread(IN HANDLE hThread, CsrThread->CreateTime = KernelTimes.CreateTime; CsrThread->ClientId = *ClientId; CsrThread->ThreadHandle = ThreadHandle; + ProtectHandle(ThreadHandle); CsrThread->Flags = 0; /* Insert the Thread into the Process */ @@ -508,7 +548,7 @@ CsrCreateRemoteThread(IN HANDLE hThread, * * @param ClientId * Pointer to the Client ID structure of the NT Thread to associate - * with this CSR Thread. + * with this CSR Thread. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL * othwerwise. @@ -520,33 +560,38 @@ NTSTATUS NTAPI CsrCreateThread(IN PCSR_PROCESS CsrProcess, IN HANDLE hThread, - IN PCLIENT_ID ClientId) + IN PCLIENT_ID ClientId, + IN BOOLEAN HaveClient) { NTSTATUS Status; - PCSR_THREAD CsrThread; + PCSR_THREAD CsrThread, CurrentThread; PCSR_PROCESS CurrentProcess; - PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; CLIENT_ID CurrentCid; KERNEL_USER_TIMES KernelTimes; - DPRINT("CSRSRV: %s called\n", __FUNCTION__); - /* Get the current thread and CID */ - CurrentCid = CurrentThread->ClientId; - - /* Acquire the Process Lock */ - CsrAcquireProcessLock(); - - /* Get the current Process and make sure the Thread is valid with this CID */ - CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, - &CurrentCid); - - /* Something is wrong if we get an empty thread back */ - if (!CurrentThread) + if (HaveClient) { - DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__); - CsrReleaseProcessLock(); - return STATUS_THREAD_IS_TERMINATING; + /* Get the current thread and CID */ + CurrentThread = NtCurrentTeb()->CsrClientThread; + CurrentCid = CurrentThread->ClientId; + + /* Acquire the Process Lock */ + CsrAcquireProcessLock(); + + /* Get the current Process and make sure the Thread is valid with this CID */ + CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid); + if (!CurrentThread) + { + DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__); + CsrReleaseProcessLock(); + return STATUS_THREAD_IS_TERMINATING; + } + } + else + { + /* Acquire the Process Lock */ + CsrAcquireProcessLock(); } /* Get the Thread Create Time */ @@ -555,9 +600,15 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess, (PVOID)&KernelTimes, sizeof(KernelTimes), NULL); + if (!NT_SUCCESS(Status)) + { + CsrReleaseProcessLock(); + return Status; + } /* Allocate a CSR Thread Structure */ - if (!(CsrThread = CsrAllocateThread(CsrProcess))) + CsrThread = CsrAllocateThread(CsrProcess); + if (!CsrThread) { DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__); CsrReleaseProcessLock(); @@ -568,6 +619,7 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess, CsrThread->CreateTime = KernelTimes.CreateTime; CsrThread->ClientId = *ClientId; CsrThread->ThreadHandle = hThread; + ProtectHandle(hThread); CsrThread->Flags = 0; /* Insert the Thread into the Process */ @@ -595,12 +647,13 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess, *--*/ VOID NTAPI -CsrDereferenceThread(PCSR_THREAD CsrThread) +CsrDereferenceThread(IN PCSR_THREAD CsrThread) { /* Acquire process lock */ CsrAcquireProcessLock(); /* Decrease reference count */ + ASSERT(CsrThread->ReferenceCount > 0); if (!(--CsrThread->ReferenceCount)) { /* Call the generic cleanup code */ @@ -624,7 +677,7 @@ CsrDereferenceThread(PCSR_THREAD CsrThread) * Pointer to the thread's startup routine. * * @param Flags - * Initial CSR Thread Flags to set to the CSR Thread. + * Initial CSR Thread Flags to set to the CSR Thread. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL * othwerwise. @@ -648,7 +701,9 @@ CsrExecServerThread(IN PVOID ThreadHandler, CsrAcquireProcessLock(); /* Allocate a CSR Thread in the Root Process */ - if (!(CsrThread = CsrAllocateThread(CsrRootProcess))) + ASSERT(CsrRootProcess != NULL); + CsrThread = CsrAllocateThread(CsrRootProcess); + if (!CsrThread) { /* Fail */ CsrReleaseProcessLock(); @@ -676,6 +731,7 @@ CsrExecServerThread(IN PVOID ThreadHandler, /* Setup the Thread Object */ CsrThread->ThreadHandle = hThread; + ProtectHandle(hThread); CsrThread->ClientId = ClientId; CsrThread->Flags = Flags; @@ -694,12 +750,12 @@ CsrExecServerThread(IN PVOID ThreadHandler, * @name CsrDestroyThread * @implemented NT4 * - * The CsrDestroyThread routine destroys the CSR Thread corresponding to + * The CsrDestroyThread routine destroys the CSR Thread corresponding to * a given Thread ID. * * @param Cid * Pointer to the Client ID Structure corresponding to the CSR - * Thread which is about to be destroyed. + * Thread which is about to be destroyed. * * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING * if the CSR Thread is already terminating. @@ -766,7 +822,7 @@ CsrDestroyThread(IN PCLIENT_ID Cid) * The CsrImpersonateClient will impersonate the given CSR Thread. * * @param CsrThread - * Pointer to the CSR Thread to impersonate. + * Pointer to the CSR Thread to impersonate. * * @return TRUE if impersionation suceeded, false otherwise. * @@ -784,27 +840,21 @@ CsrImpersonateClient(IN PCSR_THREAD CsrThread) if (!CsrThread) CsrThread = CurrentThread; /* Still no thread, something is wrong */ - if (!CsrThread) - { - /* Failure */ - return FALSE; - } + if (!CsrThread) return FALSE; /* Make the call */ Status = NtImpersonateThread(NtCurrentThread(), CsrThread->ThreadHandle, &CsrSecurityQos); - if (!NT_SUCCESS(Status)) { - /* Failure */ + DPRINT1("CSRSS: Can't impersonate client thread - Status = %lx\n", Status); + if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint(); return FALSE; } - /* Increase the impersonation count for the current thread */ + /* Increase the impersonation count for the current thread and return */ if (CurrentThread) ++CurrentThread->ImpersonationCount; - - /* Return Success */ return TRUE; } @@ -814,7 +864,7 @@ CsrImpersonateClient(IN PCSR_THREAD CsrThread) * * The CsrRevertToSelf routine will attempt to remove an active impersonation. * - * @param None. + * @param None. * * @return TRUE if the reversion was succesful, false otherwise. * @@ -837,6 +887,8 @@ CsrRevertToSelf(VOID) /* Make sure impersonation is on */ if (!CurrentThread->ImpersonationCount) { + DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n"); + DbgBreakPoint(); return FALSE; } else if (--CurrentThread->ImpersonationCount > 0) @@ -853,6 +905,7 @@ CsrRevertToSelf(VOID) sizeof(HANDLE)); /* Return TRUE or FALSE */ + ASSERT(NT_SUCCESS(Status)); return NT_SUCCESS(Status); } @@ -880,9 +933,9 @@ CsrRevertToSelf(VOID) NTSTATUS NTAPI CsrLockThreadByClientId(IN HANDLE Tid, - OUT PCSR_THREAD *CsrThread OPTIONAL) + OUT PCSR_THREAD *CsrThread) { - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY NextEntry; PCSR_THREAD CurrentThread = NULL; NTSTATUS Status = STATUS_UNSUCCESSFUL; ULONG i; @@ -890,15 +943,18 @@ CsrLockThreadByClientId(IN HANDLE Tid, /* Acquire the lock */ CsrAcquireProcessLock(); + /* Assume failure */ + ASSERT(CsrThread != NULL); + *CsrThread = NULL; + /* Convert to Hash */ i = CsrHashThread(Tid); /* Setup the List Pointers */ - ListHead = &CsrThreadHashTable[i]; - NextEntry = ListHead; + NextEntry = CsrThreadHashTable[i].Flink; /* Start Loop */ - while (NextEntry != ListHead) + while (NextEntry != &CsrThreadHashTable[i]) { /* Get the Process */ CurrentThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); @@ -907,8 +963,7 @@ CsrLockThreadByClientId(IN HANDLE Tid, if ((CurrentThread->ClientId.UniqueThread == Tid) && !(CurrentThread->Flags & CsrThreadTerminated)) { - /* Get out of here with success */ - Status = STATUS_SUCCESS; + /* Get out of here */ break; } @@ -916,20 +971,25 @@ CsrLockThreadByClientId(IN HANDLE Tid, NextEntry = NextEntry->Flink; } + /* Nothing found if we got back to the list */ + if (NextEntry == &CsrThreadHashTable[i]) CurrentThread = NULL; + /* Did the loop find something? */ - if (NT_SUCCESS(Status)) + if (CurrentThread) { /* Reference the found thread */ + Status = STATUS_SUCCESS; CurrentThread->ReferenceCount++; + *CsrThread = CurrentThread; } else { /* Nothing found, release the lock */ + Status = STATUS_UNSUCCESSFUL; CsrReleaseProcessLock(); } - /* Return the status and thread */ - if (CsrThread) *CsrThread = CurrentThread; + /* Return the status */ return Status; } @@ -937,11 +997,11 @@ CsrLockThreadByClientId(IN HANDLE Tid, * @name CsrReferenceThread * @implemented NT4 * - * The CsrReferenceThread routine increases the active reference count of + * The CsrReferenceThread routine increases the active reference count of * a CSR Thread. * * @param CsrThread - * Pointer to the CSR Thread whose reference count will be increased. + * Pointer to the CSR Thread whose reference count will be increased. * * @return None. * @@ -955,6 +1015,10 @@ CsrReferenceThread(PCSR_THREAD CsrThread) /* Acquire process lock */ CsrAcquireProcessLock(); + /* Sanity checks */ + ASSERT(CsrThread->Flags & CsrThreadTerminated); // CSR_THREAD_DESTROYED in ASSERT + ASSERT(CsrThread->ReferenceCount != 0); + /* Increment reference count */ CsrThread->ReferenceCount++; @@ -969,7 +1033,7 @@ CsrReferenceThread(PCSR_THREAD CsrThread) * The CsrUnlockThread undoes a previous CsrLockThreadByClientId operation. * * @param CsrThread - * Pointer to a previously locked CSR Thread. + * Pointer to a previously locked CSR Thread. * * @return STATUS_SUCCESS. * @@ -981,6 +1045,7 @@ NTAPI CsrUnlockThread(PCSR_THREAD CsrThread) { /* Dereference the Thread */ + ASSERT(ProcessStructureListLocked()); CsrLockedDereferenceThread(CsrThread); /* Release the lock and return */ diff --git a/reactos/subsystems/csr/csrsrv/wait.c b/reactos/subsystems/csr/csrsrv/wait.c index 08a840245d0..00d0bdf3108 100644 --- a/reactos/subsystems/csr/csrsrv/wait.c +++ b/reactos/subsystems/csr/csrsrv/wait.c @@ -62,7 +62,8 @@ CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction, WaitApiMessage->Header.u1.s1.TotalLength; /* Allocate the Wait Block */ - if (!(WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size))) + WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size); + if (!WaitBlock) { /* Fail */ WaitApiMessage->Status = STATUS_NO_MEMORY; @@ -74,8 +75,9 @@ CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction, WaitBlock->WaitThread = CsrWaitThread; WaitBlock->WaitContext = WaitContext; WaitBlock->WaitFunction = WaitFunction; - InitializeListHead(&WaitBlock->UserWaitList); - InitializeListHead(&WaitBlock->WaitList); + WaitBlock->UserWaitList.Flink = NULL; + WaitBlock->UserWaitList.Blink = NULL; + WaitBlock->WaitList = WaitBlock->UserWaitList; /* Copy the message */ RtlMoveMemory(&WaitBlock->WaitApiMessage, @@ -173,7 +175,7 @@ CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock, WaitBlock->WaitFunction = NULL; } - /* The wait suceeded*/ + /* The wait suceeded */ return TRUE; } @@ -237,10 +239,9 @@ CsrCreateWait(IN PLIST_ENTRY WaitList, CsrAcquireWaitLock(); /* Make sure the thread wasn't destroyed */ - if (CsrWaitThread && (CsrWaitThread->Flags & CsrThreadTerminated)) + if (CsrWaitThread->Flags & CsrThreadTerminated) { /* Fail the wait */ - CsrWaitThread->WaitBlock = NULL; RtlFreeHeap(CsrHeap, 0, WaitBlock); CsrReleaseWaitLock(); return FALSE; @@ -275,7 +276,7 @@ VOID NTAPI CsrDereferenceWait(IN PLIST_ENTRY WaitList) { - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY NextEntry; PCSR_WAIT_BLOCK WaitBlock; /* Acquire the Process and Wait Locks */ @@ -283,11 +284,10 @@ CsrDereferenceWait(IN PLIST_ENTRY WaitList) CsrAcquireWaitLock(); /* Set the list pointers */ - ListHead = WaitList; - NextEntry = ListHead->Flink; + NextEntry = WaitList->Flink; /* Start the loop */ - while (NextEntry != ListHead) + while (NextEntry != WaitList) { /* Get the wait block */ WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList); @@ -346,18 +346,17 @@ NTAPI CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry, IN PLIST_ENTRY WaitList) { - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY NextEntry; PCSR_WAIT_BLOCK WaitBlock; /* Acquire the Wait Lock */ CsrAcquireWaitLock(); /* Set the List pointers */ - ListHead = WaitList; - NextEntry = ListHead->Flink; + NextEntry = WaitList->Flink; /* Start looping */ - while (NextEntry != ListHead) + while (NextEntry != WaitList) { /* Get the Wait block */ WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList); @@ -407,7 +406,7 @@ CsrNotifyWait(IN PLIST_ENTRY WaitList, IN PVOID WaitArgument1, IN PVOID WaitArgument2) { - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY NextEntry; PCSR_WAIT_BLOCK WaitBlock; BOOLEAN NotifySuccess = FALSE; @@ -415,11 +414,10 @@ CsrNotifyWait(IN PLIST_ENTRY WaitList, CsrAcquireWaitLock(); /* Set the List pointers */ - ListHead = WaitList; - NextEntry = ListHead->Flink; + NextEntry = WaitList->Flink; /* Start looping */ - while (NextEntry != ListHead) + while (NextEntry != WaitList) { /* Get the Wait block */ WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList); diff --git a/reactos/subsystems/csr/main.c b/reactos/subsystems/csr/main.c index b52f028274f..af89bec210e 100644 --- a/reactos/subsystems/csr/main.c +++ b/reactos/subsystems/csr/main.c @@ -1,22 +1,3 @@ -/* $Id$ - * -------------------------------------------------------------------- - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * -------------------------------------------------------------------- - */ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS CSR Sub System