diff --git a/subsystems/csr/CMakeLists.txt b/subsystems/csr/CMakeLists.txt deleted file mode 100644 index 29ccac1a8da..00000000000 --- a/subsystems/csr/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ - -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/subsystems/csr/csr.rc b/subsystems/csr/csr.rc deleted file mode 100644 index c5d32a1013d..00000000000 --- a/subsystems/csr/csr.rc +++ /dev/null @@ -1,4 +0,0 @@ -#define REACTOS_STR_FILE_DESCRIPTION "Client/Server Runtime Process\0" -#define REACTOS_STR_INTERNAL_NAME "csrss\0" -#define REACTOS_STR_ORIGINAL_FILENAME "csrss.exe\0" -#include diff --git a/subsystems/csr/csrsrv/CMakeLists.txt b/subsystems/csr/csrsrv/CMakeLists.txt deleted file mode 100644 index 8c48af51816..00000000000 --- a/subsystems/csr/csrsrv/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ - -include_directories(${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include) -include_directories(${REACTOS_SOURCE_DIR}/include/reactos/subsys) - -spec2def(csrsrv2.dll csrsrv2.spec ADD_IMPORTLIB) - -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) - diff --git a/subsystems/csr/csrsrv/api.c b/subsystems/csr/csrsrv/api.c deleted file mode 100644 index e7257095f14..00000000000 --- a/subsystems/csr/csrsrv/api.c +++ /dev/null @@ -1,1650 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System - * FILE: subsys/csr/csrsrv/api.c - * PURPOSE: CSR Server DLL API LPC Implementation - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES ******************************************************************/ - -#include "srv.h" - -#define NDEBUG -#include - -/* DATA **********************************************************************/ -BOOLEAN (*CsrClientThreadSetup)(VOID) = NULL; -ULONG CsrMaxApiRequestThreads; -UNICODE_STRING CsrSbApiPortName; -UNICODE_STRING CsrApiPortName; -HANDLE CsrSbApiPort; -HANDLE CsrApiPort; -PCSR_THREAD CsrSbApiRequestThreadPtr; -volatile LONG CsrpStaticThreadCount; -volatile LONG CsrpDynamicThreadTotal; - -/* PRIVATE FUNCTIONS *********************************************************/ - -/*++ - * @name CsrpCheckRequestThreads - * - * 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. - * - * @param None. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * if a new thread couldn't be created. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrpCheckRequestThreads(VOID) -{ - HANDLE hThread; - CLIENT_ID ClientId; - NTSTATUS Status; - - /* Decrease the count, and see if we're out */ - if (!(_InterlockedDecrement(&CsrpStaticThreadCount))) - { - /* Check if we've still got space for a Dynamic Thread */ - if (CsrpDynamicThreadTotal < CsrMaxApiRequestThreads) - { - /* Create a new dynamic thread */ - Status = RtlCreateUserThread(NtCurrentProcess(), - NULL, - TRUE, - 0, - 0, - 0, - (PVOID)CsrApiRequestThread, - NULL, - &hThread, - &ClientId); - /* Check success */ - if (NT_SUCCESS(Status)) - { - /* Increase the thread counts */ - _InterlockedIncrement(&CsrpStaticThreadCount); - _InterlockedIncrement(&CsrpDynamicThreadTotal); - - /* Add a new server thread */ - if (CsrAddStaticServerThread(hThread, - &ClientId, - CsrThreadIsServerThread)) - { - /* Activate it */ - NtResumeThread(hThread,NULL); - } - else - { - /* Failed to create a new static thread */ - _InterlockedDecrement(&CsrpStaticThreadCount); - _InterlockedDecrement(&CsrpDynamicThreadTotal); - - /* Terminate it */ - NtTerminateThread(hThread,0); - NtClose(hThread); - - /* Return */ - return STATUS_UNSUCCESSFUL; - } - } - } - } - - /* Success */ - return STATUS_SUCCESS; -} - -/*++ - * @name CsrSbApiPortInitialize - * - * The CsrSbApiPortInitialize routine initializes the LPC Port used for - * communications with the Session Manager (SM) and initializes the static - * thread that will handle connection requests and APIs. - * - * @param None - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrSbApiPortInitialize(VOID) -{ - ULONG Size; - PSECURITY_DESCRIPTOR PortSd; - OBJECT_ATTRIBUTES ObjectAttributes; - NTSTATUS Status; - HANDLE hRequestThread; - CLIENT_ID ClientId; - - /* Calculate how much space we'll need for the Port Name */ - Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR); - - /* 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 */ - Status = CsrCreateLocalSystemSD(&PortSd); - if (!NT_SUCCESS(Status)) return Status; - - /* Initialize the Attributes */ - InitializeObjectAttributes(&ObjectAttributes, - &CsrSbApiPortName, - 0, - NULL, - PortSd); - - /* Create the Port Object */ - Status = NtCreatePort(&CsrSbApiPort, - &ObjectAttributes, - sizeof(SB_CONNECTION_INFO), - sizeof(SB_API_MSG), - 32 * sizeof(SB_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); - } - } - - return Status; -} - -/*++ - * @name CsrApiPortInitialize - * - * The CsrApiPortInitialize routine initializes the LPC Port used for - * communications with the Client/Server Runtime (CSR) and initializes the - * static thread that will handle connection requests and APIs. - * - * @param None - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrApiPortInitialize(VOID) -{ - ULONG Size; - OBJECT_ATTRIBUTES ObjectAttributes; - NTSTATUS Status; - HANDLE hRequestEvent, hThread; - CLIENT_ID ClientId; - PLIST_ENTRY ListHead, NextEntry; - PCSR_THREAD ServerThread; - - /* Calculate how much space we'll need for the Port Name */ - Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR); - - /* 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 */ - - /* Initialize the Attributes */ - InitializeObjectAttributes(&ObjectAttributes, - &CsrApiPortName, - 0, - NULL, - NULL /* FIXME*/); - - /* Create the Port Object */ - Status = NtCreatePort(&CsrApiPort, - &ObjectAttributes, - sizeof(CSR_CONNECTION_INFO), - sizeof(CSR_API_MESSAGE), - 16 * PAGE_SIZE); - 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) - { - /* 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); - } - } - } - - /* Return */ - return Status; -} - -/*++ - * @name CsrApiRequestThread - * - * The CsrApiRequestThread routine handles incoming messages or connection - * requests on the CSR API LPC Port. - * - * @param Parameter - * System-default user-defined parameter. Unused. - * - * @return The thread exit code, if the thread is terminated. - * - * @remarks Before listening on the port, the routine will first attempt - * to connect to the user subsystem. - * - *--*/ -NTSTATUS -NTAPI -CsrApiRequestThread(IN PVOID Parameter) -{ - PTEB Teb = NtCurrentTeb(); - LARGE_INTEGER TimeOut; - PCSR_THREAD CurrentThread, CsrThread; - NTSTATUS Status; - PCSR_API_MESSAGE ReplyMsg; - CSR_API_MESSAGE ReceiveMsg; - PCSR_PROCESS CsrProcess; - PHARDERROR_MSG HardErrorMsg; - PVOID PortContext; - PCSR_SERVER_DLL ServerDll; - PCLIENT_DIED_MSG ClientDiedMsg; - PDBGKM_MSG DebugMessage; - ULONG ServerId, ApiId, Reply, MessageType, i; - HANDLE ReplyPort; - - /* 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); - } - - /* Get our thread */ - CurrentThread = Teb->CsrClientThread; - - /* If we got an event... */ - if (Parameter) - { - /* Set it, to let stuff waiting on us load */ - Status = NtSetEvent((HANDLE)Parameter, NULL); - ASSERT(NT_SUCCESS(Status)); - - /* Increase the Thread Counts */ - _InterlockedIncrement(&CsrpStaticThreadCount); - _InterlockedIncrement(&CsrpDynamicThreadTotal); - } - - /* Now start the loop */ - while (TRUE) - { - /* 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(ReplyPort, - &PortContext, - &ReplyMsg->Header, - &ReceiveMsg.Header); - - /* Check if we didn't get success */ - if (Status != STATUS_SUCCESS) - { - /* 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; - 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 */ - Teb->RealClientId = ReceiveMsg.Header.ClientId; - - /* Get the Message Type */ - MessageType = ReceiveMsg.Header.u2.s2.Type; - - /* Handle connection requests */ - if (MessageType == LPC_CONNECTION_REQUEST) - { - /* Handle the Connection Request */ - CsrApiHandleConnectionRequest(&ReceiveMsg); - ReplyPort = CsrApiPort; - ReplyMsg = NULL; - continue; - } - - /* It's some other kind of request. Get the lock for the lookup */ - CsrAcquireProcessLock(); - - /* Now do the lookup to get the CSR_THREAD */ - CsrThread = CsrLocateThreadByClientId(&CsrProcess, - &ReceiveMsg.Header.ClientId); - - /* Did we find a thread? */ - if (!CsrThread) - { - /* This wasn't a CSR Thread, release lock */ - CsrReleaseProcessLock(); - - /* If this was an exception, handle it */ - if (MessageType == LPC_EXCEPTION) - { - ReplyMsg = &ReceiveMsg; - ReplyPort = CsrApiPort; - ReplyMsg->Status = DBG_CONTINUE; - } - else if (MessageType == LPC_PORT_CLOSED || - MessageType == LPC_CLIENT_DIED) - { - /* The Client or Port are gone, loop again */ - ReplyMsg = NULL; - ReplyPort = CsrApiPort; - } - else if (MessageType == LPC_ERROR_EVENT) - { - /* If it's a hard error, handle this too */ - HardErrorMsg = (PHARDERROR_MSG)&ReceiveMsg; - - /* Default it to unhandled */ - HardErrorMsg->Response = ResponseNotHandled; - - /* Check if there are free api threads */ - CsrpCheckRequestThreads(); - if (CsrpStaticThreadCount) - { - /* Loop every Server DLL */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Get the Server DLL */ - ServerDll = CsrLoadedServerDll[i]; - - /* Check if it's valid and if it has a Hard Error Callback */ - if ((ServerDll) && (ServerDll->HardErrorCallback)) - { - /* Call it */ - ServerDll->HardErrorCallback(NULL, HardErrorMsg); - - /* If it's handled, get out of here */ - if (HardErrorMsg->Response != ResponseNotHandled) break; - } - } - } - - /* Increase the thread count */ - _InterlockedIncrement(&CsrpStaticThreadCount); - - /* If the response was 0xFFFFFFFF, we'll ignore it */ - if (HardErrorMsg->Response == 0xFFFFFFFF) - { - ReplyMsg = NULL; - ReplyPort = CsrApiPort; - } - else - { - ReplyMsg = &ReceiveMsg; - } - } - else if (MessageType == LPC_REQUEST) - { - /* 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) - { - /* 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 = NULL; - 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 = 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 */ - continue; - } - - /* We have a valid thread, was this an LPC Request? */ - if (MessageType != LPC_REQUEST) - { - /* It's not an API, check if the client died */ - if (MessageType == LPC_CLIENT_DIED) - { - /* Get the information and check if it matches our thread */ - ClientDiedMsg = (PCLIENT_DIED_MSG)&ReceiveMsg; - if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart) - { - /* Reference the thread */ - CsrLockedReferenceThread(CsrThread); - - /* Destroy the thread in the API Message */ - CsrDestroyThread(&ReceiveMsg.Header.ClientId); - - /* Check if the thread was actually ourselves */ - if (CsrProcess->ThreadCount == 1) - { - /* Kill the process manually here */ - CsrDestroyProcess(&CsrThread->ClientId, 0); - } - - /* Remove our extra reference */ - CsrLockedDereferenceThread(CsrThread); - } - - /* Release the lock and keep looping */ - CsrReleaseProcessLock(); - ReplyMsg = NULL; - ReplyPort = CsrApiPort; - continue; - } - - /* Reference the thread and release the lock */ - CsrLockedReferenceThread(CsrThread); - CsrReleaseProcessLock(); - - /* Check if this was an exception */ - if (MessageType == LPC_EXCEPTION) - { - /* Kill the process */ - NtTerminateProcess(CsrProcess->ProcessHandle, STATUS_ABANDONED); - - /* Destroy it from CSR */ - CsrDestroyProcess(&ReceiveMsg.Header.ClientId, STATUS_ABANDONED); - - /* Return a Debug Message */ - DebugMessage = (PDBGKM_MSG)&ReceiveMsg; - DebugMessage->ReturnedStatus = DBG_CONTINUE; - ReplyMsg = &ReceiveMsg; - ReplyPort = CsrApiPort; - - /* Remove our extra reference */ - CsrDereferenceThread(CsrThread); - } - else if (MessageType == LPC_ERROR_EVENT) - { - /* If it's a hard error, handle this too */ - HardErrorMsg = (PHARDERROR_MSG)&ReceiveMsg; - - /* Default it to unhandled */ - HardErrorMsg->Response = ResponseNotHandled; - - /* Check if there are free api threads */ - CsrpCheckRequestThreads(); - if (CsrpStaticThreadCount) - { - /* Loop every Server DLL */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Get the Server DLL */ - ServerDll = CsrLoadedServerDll[i]; - - /* Check if it's valid and if it has a Hard Error Callback */ - if ((ServerDll) && (ServerDll->HardErrorCallback)) - { - /* Call it */ - ServerDll->HardErrorCallback(CsrThread, HardErrorMsg); - - /* If it's handled, get out of here */ - if (HardErrorMsg->Response != ResponseNotHandled) break; - } - } - } - - /* Increase the thread count */ - _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 - { - /* Something else */ - CsrDereferenceThread(CsrThread); - ReplyMsg = NULL; - } - - /* Keep looping */ - continue; - } - - /* We got an API Request */ - CsrLockedReferenceThread(CsrThread); - CsrReleaseProcessLock(); - - /* 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! */ - NtTerminateThread(NtCurrentThread(), Status); - return Status; -} - -/*++ - * @name CsrApiHandleConnectionRequest - * - * The CsrApiHandleConnectionRequest routine handles and accepts a new - * connection request to the CSR API LPC Port. - * - * @param ApiMessage - * Pointer to the incoming CSR API Message which contains the - * connection request. - * - * @return STATUS_SUCCESS in case of success, or status code which caused - * the routine to error. - * - * @remarks This routine is responsible for attaching the Shared Section to - * new clients connecting to CSR. - * - *--*/ -NTSTATUS -NTAPI -CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage) -{ - PCSR_THREAD CsrThread = NULL; - PCSR_PROCESS CsrProcess = NULL; - NTSTATUS Status = STATUS_SUCCESS; - PCSR_CONNECTION_INFO ConnectInfo = &ApiMessage->ConnectionInfo; - BOOLEAN AllowConnection = FALSE; - REMOTE_PORT_VIEW RemotePortView; - HANDLE hPort; - - /* Acquire the Process Lock */ - CsrAcquireProcessLock(); - - /* Lookup the CSR Thread */ - CsrThread = CsrLocateThreadByClientId(NULL, &ApiMessage->Header.ClientId); - - /* Check if we have a thread */ - if (CsrThread) - { - /* Get the Process */ - CsrProcess = CsrThread->Process; - - /* Make sure we have a Process as well */ - if (CsrProcess) - { - /* Reference the Process */ - CsrLockedReferenceProcess(CsrThread->Process); - - /* Release the lock */ - CsrReleaseProcessLock(); - - /* Duplicate the Object Directory */ - Status = NtDuplicateObject(NtCurrentProcess(), - CsrObjectDirectory, - CsrProcess->ProcessHandle, - &ConnectInfo->ObjectDirectory, - 0, - 0, - DUPLICATE_SAME_ACCESS | - DUPLICATE_SAME_ATTRIBUTES); - - /* Acquire the lock */ - CsrAcquireProcessLock(); - - /* Check for success */ - if (NT_SUCCESS(Status)) - { - /* Attach the Shared Section */ - Status = CsrSrvAttachSharedSection(CsrProcess, ConnectInfo); - - /* Check how this went */ - if (NT_SUCCESS(Status)) AllowConnection = TRUE; - } - - /* Dereference the project */ - CsrLockedDereferenceProcess(CsrProcess); - } - } - - /* Release the lock */ - CsrReleaseProcessLock(); - - /* Setup the Port View Structure */ - RemotePortView.Length = sizeof(REMOTE_PORT_VIEW); - RemotePortView.ViewSize = 0; - RemotePortView.ViewBase = NULL; - - /* Save the Process ID */ - ConnectInfo->ProcessId = NtCurrentTeb()->ClientId.UniqueProcess; - - /* Accept the Connection */ - Status = NtAcceptConnectPort(&hPort, - AllowConnection ? UlongToPtr(CsrProcess->SequenceNumber) : 0, - &ApiMessage->Header, - AllowConnection, - NULL, - &RemotePortView); - 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; - CsrProcess->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase + - (ULONG_PTR)RemotePortView.ViewSize); - - /* Complete the connection */ - Status = NtCompleteConnectPort(hPort); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status); - } - } - else - { - DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n", - ApiMessage->Header.ClientId.UniqueProcess, - ApiMessage->Header.ClientId.UniqueThread); - } - - /* Return status to caller */ - return Status; -} - -/*++ - * @name CsrSbApiRequestThread - * - * The CsrSbApiRequestThread routine handles incoming messages or connection - * requests on the SM API LPC Port. - * - * @param Parameter - * System-default user-defined parameter. Unused. - * - * @return The thread exit code, if the thread is terminated. - * - * @remarks Before listening on the port, the routine will first attempt - * to connect to the user subsystem. - * - *--*/ -VOID -NTAPI -CsrSbApiRequestThread(IN PVOID Parameter) -{ - NTSTATUS Status; - SB_API_MSG ReceiveMsg; - PSB_API_MSG ReplyMsg = NULL; - PVOID PortContext; - ULONG MessageType; - - /* Start the loop */ - while (TRUE) - { - /* Wait for a message to come in */ - Status = NtReplyWaitReceivePort(CsrSbApiPort, - &PortContext, - &ReplyMsg->h, - &ReceiveMsg.h); - - /* Check if we didn't get 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.h.u2.s2.Type; - - /* Check if this is a connection request */ - if (MessageType == LPC_CONNECTION_REQUEST) - { - /* Handle connection request */ - CsrSbApiHandleConnectionRequest(&ReceiveMsg); - - /* Start over */ - ReplyMsg = NULL; - continue; - } - - /* Check if the port died */ - if (MessageType == LPC_PORT_CLOSED) - { - /* Close the handle if we have one */ - if (PortContext) NtClose((HANDLE)PortContext); - - /* Client died, start over */ - ReplyMsg = NULL; - continue; - } - else if (MessageType == LPC_CLIENT_DIED) - { - /* Client died, start over */ - ReplyMsg = NULL; - continue; - } - - /* - * 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.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.ApiNumber < SbpMaxApiNumber) - { - /* Call the API */ - if (!CsrServerSbApiDispatch[ReceiveMsg.ApiNumber](&ReceiveMsg)) - { - /* It failed, so return nothing */ - ReplyMsg = NULL; - } - } - else - { - /* We don't support this API Number */ - ReplyMsg->ReturnValue = STATUS_NOT_IMPLEMENTED; - } - } -} - -/*++ - * @name CsrSbApiHandleConnectionRequest - * - * The CsrSbApiHandleConnectionRequest routine handles and accepts a new - * connection request to the SM API LPC Port. - * - * @param ApiMessage - * Pointer to the incoming CSR API Message which contains the - * connection request. - * - * @return STATUS_SUCCESS in case of success, or status code which caused - * the routine to error. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message) -{ - NTSTATUS Status; - REMOTE_PORT_VIEW RemotePortView; - HANDLE hPort; - - /* Set the Port View Structure Length */ - RemotePortView.Length = sizeof(REMOTE_PORT_VIEW); - - /* Accept the connection */ - Status = NtAcceptConnectPort(&hPort, - NULL, - (PPORT_MESSAGE)Message, - TRUE, - NULL, - &RemotePortView); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: Sb Accept Connection failed %lx\n", Status); - return Status; - } - - /* Complete the Connection */ - Status = NtCompleteConnectPort(hPort); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: Sb Complete Connection failed %lx\n",Status); - } - - /* Return status */ - return Status; -} - -/* PUBLIC FUNCTIONS **********************************************************/ - -/*++ - * @name CsrCallServerFromServer - * @implemented NT4 - * - * The CsrCallServerFromServer routine calls a CSR API from within a server. - * It avoids using LPC messages since the request isn't coming from a client. - * - * @param ReceiveMsg - * Pointer to the CSR API Message to send to the server. - * - * @param ReplyMsg - * Pointer to the CSR API Message to receive from the server. - * - * @return STATUS_SUCCESS in case of success, STATUS_ILLEGAL_FUNCTION - * if the opcode is invalid, or STATUS_ACCESS_VIOLATION if there - * was a problem executing the API. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg, - PCSR_API_MESSAGE ReplyMsg) -{ - ULONG ServerId; - PCSR_SERVER_DLL ServerDll; - ULONG ApiId; - ULONG Reply; - NTSTATUS Status; - - /* 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 */ - 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); - ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION; - return STATUS_ILLEGAL_FUNCTION; - } - 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) || - ((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 - { - /* Call the API and get the result */ - Status = ServerDll->DispatchTable[ApiId](ReceiveMsg, &Reply); - - /* Return the result, no matter what it is */ - ReplyMsg->Status = Status; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* If we got an exception, return access violation */ - ReplyMsg->Status = STATUS_ACCESS_VIOLATION; - } - _SEH2_END; - - /* Return success */ - return STATUS_SUCCESS; -} - -/*++ - * @name CsrConnectToUser - * @implemented NT4 - * - * The CsrConnectToUser connects to the User subsystem. - * - * @param None - * - * @return A pointer to the CSR Thread - * - * @remarks None. - * - *--*/ -PCSR_THREAD -NTAPI -CsrConnectToUser(VOID) -{ - NTSTATUS Status; - ANSI_STRING DllName; - UNICODE_STRING TempName; - HANDLE hUser32; - STRING StartupName; - PTEB Teb = NtCurrentTeb(); - PCSR_THREAD CsrThread; - BOOLEAN Connected; - - /* Check if we didn't already find it */ - if (!CsrClientThreadSetup) - { - /* Get the DLL Handle for user32.dll */ - RtlInitAnsiString(&DllName, "user32"); - RtlAnsiStringToUnicodeString(&TempName, &DllName, TRUE); - Status = LdrGetDllHandle(NULL, - NULL, - &TempName, - &hUser32); - RtlFreeUnicodeString(&TempName); - - /* If we got teh handle, get the Client Thread Startup Entrypoint */ - if (NT_SUCCESS(Status)) - { - RtlInitAnsiString(&StartupName,"ClientThreadSetup"); - Status = LdrGetProcedureAddress(hUser32, - &StartupName, - 0, - (PVOID)&CsrClientThreadSetup); - } - } - - /* Connect to user32 */ - _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 */ - return CsrThread; -} - -/*++ - * @name CsrQueryApiPort - * @implemented NT4 - * - * The CsrQueryApiPort routine returns a handle to the CSR API LPC port. - * - * @param None. - * - * @return A handle to the port. - * - * @remarks None. - * - *--*/ -HANDLE -NTAPI -CsrQueryApiPort(VOID) -{ - DPRINT("CSRSRV: %s called\n", __FUNCTION__); - return CsrApiPort; -} - -/*++ - * @name CsrCaptureArguments - * @implemented NT5.1 - * - * The CsrCaptureArguments routine validates a CSR Capture Buffer and - * re-captures it into a server CSR Capture Buffer. - * - * @param CsrThread - * Pointer to the CSR Thread performing the validation. - * - * @param ApiMessage - * Pointer to the CSR API Message containing the Capture Buffer - * that needs to be validated. - * - * @return TRUE if validation succeeded, FALSE otherwise. - * - * @remarks None. - * - *--*/ -BOOLEAN -NTAPI -CsrCaptureArguments(IN PCSR_THREAD CsrThread, - IN PCSR_API_MESSAGE ApiMessage) -{ - PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL, RemoteCaptureBuffer = NULL; - ULONG LocalLength = 0, PointerCount = 0; - SIZE_T BufferDistance = 0; - ULONG_PTR **PointerOffsets = NULL, *CurrentPointer = NULL; - - /* Use SEH to make sure this is valid */ - _SEH2_TRY - { - /* Get the buffer we got from whoever called NTDLL */ - LocalCaptureBuffer = ApiMessage->CsrCaptureData; - LocalLength = LocalCaptureBuffer->Size; - - /* Now check if the buffer is inside our mapped section */ - if (((ULONG_PTR)LocalCaptureBuffer < CsrThread->Process->ClientViewBase) || - (((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); - } - - /* Check if the Length is valid */ - if (((LocalCaptureBuffer->PointerCount * 4 + sizeof(CSR_CAPTURE_BUFFER)) > - LocalLength) ||(LocalLength > MAXWORD)) - { - /* Return failure */ - DPRINT1("*** CSRSS: CaptureBuffer %p has bad length\n", LocalCaptureBuffer); - DbgBreakPoint(); - ApiMessage->Status = STATUS_INVALID_PARAMETER; - _SEH2_YIELD(return FALSE); - } - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return failure */ - ApiMessage->Status = STATUS_INVALID_PARAMETER; - _SEH2_YIELD(return FALSE); - } _SEH2_END; - - /* We validated the incoming buffer, now allocate the remote one */ - RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, 0, LocalLength); - if (!RemoteCaptureBuffer) - { - /* We're out of memory */ - ApiMessage->Status = STATUS_NO_MEMORY; - return FALSE; - } - - /* Copy the client's buffer */ - RtlMoveMemory(RemoteCaptureBuffer, LocalCaptureBuffer, LocalLength); - - /* Copy the length */ - RemoteCaptureBuffer->Size = LocalLength; - - /* Calculate the difference between our buffer and the client's */ - BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer; - - /* Save the pointer count and offset pointer */ - PointerCount = RemoteCaptureBuffer->PointerCount; - PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1); - - /* Start the loop */ - while (PointerCount) - { - /* Get the current pointer */ - if ((CurrentPointer = *PointerOffsets++)) - { - /* Add it to the CSR Message structure */ - CurrentPointer += (ULONG_PTR)ApiMessage; - - /* Validate the bounds of the current pointer */ - if ((*CurrentPointer >= CsrThread->Process->ClientViewBase) && - (*CurrentPointer < CsrThread->Process->ClientViewBounds)) - { - /* Modify the pointer to take into account its new position */ - *CurrentPointer += BufferDistance; - } - else - { - /* Invalid pointer, fail */ - DPRINT1("*** CSRSS: CaptureBuffer MessagePointer outside of ClientView\n"); - DbgBreakPoint(); - ApiMessage->Status = STATUS_INVALID_PARAMETER; - } - } - - /* Move to the next Pointer */ - PointerCount--; - } - - /* Check if we got success */ - if (ApiMessage->Status != STATUS_SUCCESS) - { - /* Failure. Free the buffer and return*/ - RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer); - return FALSE; - } - else - { - /* Success, save the previous buffer */ - RemoteCaptureBuffer->PreviousCaptureBuffer = LocalCaptureBuffer; - ApiMessage->CsrCaptureData = RemoteCaptureBuffer; - } - - /* Success */ - return TRUE; -} - -/*++ - * @name CsrReleaseCapturedArguments - * @implemented NT5.1 - * - * The CsrReleaseCapturedArguments routine releases a Capture Buffer - * that was previously captured with CsrCaptureArguments. - * - * @param ApiMessage - * Pointer to the CSR API Message containing the Capture Buffer - * that needs to be released. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage) -{ - PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer; - SIZE_T BufferDistance; - ULONG PointerCount; - ULONG_PTR **PointerOffsets, *CurrentPointer; - - /* Get the capture buffers */ - RemoteCaptureBuffer = ApiMessage->CsrCaptureData; - LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer; - - /* Free the previous one */ - RemoteCaptureBuffer->PreviousCaptureBuffer = NULL; - - /* Find out the difference between the two buffers */ - BufferDistance = (ULONG_PTR)LocalCaptureBuffer - (ULONG_PTR)RemoteCaptureBuffer; - - /* Save the pointer count and offset pointer */ - PointerCount = RemoteCaptureBuffer->PointerCount; - PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1); - - /* Start the loop */ - while (PointerCount) - { - /* Get the current pointer */ - CurrentPointer = *PointerOffsets++; - if (CurrentPointer) - { - /* Add it to the CSR Message structure */ - CurrentPointer += (ULONG_PTR)ApiMessage; - - /* Modify the pointer to take into account its new position */ - *CurrentPointer += BufferDistance; - } - - /* Move to the next Pointer */ - PointerCount--; - } - - /* Copy the data back */ - RtlMoveMemory(LocalCaptureBuffer, RemoteCaptureBuffer, RemoteCaptureBuffer->Size); - - /* Free our allocated buffer */ - RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer); -} - -/*++ - * @name CsrValidateMessageBuffer - * @implemented NT5.1 - * - * The CsrValidateMessageBuffer routine validates a captured message buffer - * present in the CSR Api Message - * - * @param ApiMessage - * Pointer to the CSR API Message containing the CSR Capture Buffer. - * - * @param Buffer - * Pointer to the message buffer to validate. - * - * @param ArgumentSize - * Size of the message to check. - * - * @param ArgumentCount - * Number of messages to check. - * - * @return TRUE if validation suceeded, FALSE otherwise. - * - * @remarks None. - * - *--*/ -BOOLEAN -NTAPI -CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, - IN PVOID *Buffer, - IN ULONG ArgumentSize, - IN ULONG ArgumentCount) -{ - PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData; - SIZE_T BufferDistance; - ULONG PointerCount, i; - ULONG_PTR **PointerOffsets, *CurrentPointer; - - /* Make sure there are some arguments */ - if (!ArgumentCount) return FALSE; - - /* Check if didn't get a buffer and there aren't any arguments to check */ - if (!(*Buffer) && (!(ArgumentCount * ArgumentSize))) return TRUE; - - /* Check if we have no capture buffer */ - if (!CaptureBuffer) - { - /* In this case, check only the Process ID */ - if (NtCurrentTeb()->ClientId.UniqueProcess == - ApiMessage->Header.ClientId.UniqueProcess) - { - /* There is a match, validation succeeded */ - return TRUE; - } - } - else - { - /* Make sure that there is still space left in the buffer */ - if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) < - (ArgumentCount * ArgumentSize)) - { - /* Find out the difference between the two buffers */ - BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage; - - /* Save the pointer count */ - PointerCount = CaptureBuffer->PointerCount; - PointerOffsets = (ULONG_PTR**)(CaptureBuffer + 1); - - /* Start the loop */ - for (i = 0; i < PointerCount; i++) - { - /* Get the current pointer */ - CurrentPointer = *PointerOffsets++; - - /* Check if its' equal to the difference */ - if (*CurrentPointer == BufferDistance) return TRUE; - } - } - } - - /* Failure */ - DbgPrint("CSRSRV: Bad message buffer %p\n", ApiMessage); - DbgBreakPoint(); - return FALSE; -} - -/*++ - * @name CsrValidateMessageString - * @implemented NT5.1 - * - * The CsrValidateMessageString validates a captured Wide-Character String - * present in a CSR API Message. - * - * @param ApiMessage - * Pointer to the CSR API Message containing the CSR Capture Buffer. - * - * @param MessageString - * Pointer to the buffer containing the string to validate. - * - * @return TRUE if validation suceeded, FALSE otherwise. - * - * @remarks None. - * - *--*/ -BOOLEAN -NTAPI -CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage, - IN LPWSTR *MessageString) -{ - DPRINT1("CSRSRV: %s called\n", __FUNCTION__); - return FALSE; -} - -/* EOF */ diff --git a/subsystems/csr/csrsrv/csrsrv.rc b/subsystems/csr/csrsrv/csrsrv.rc deleted file mode 100644 index 658072d09b8..00000000000 --- a/subsystems/csr/csrsrv/csrsrv.rc +++ /dev/null @@ -1,5 +0,0 @@ -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS CSR Core Server\0" -#define REACTOS_STR_INTERNAL_NAME "csrsrv\0" -#define REACTOS_STR_ORIGINAL_FILENAME "csrsrv.dll\0" -#include diff --git a/subsystems/csr/csrsrv/csrsrv2.spec b/subsystems/csr/csrsrv/csrsrv2.spec deleted file mode 100644 index e3794208fe9..00000000000 --- a/subsystems/csr/csrsrv/csrsrv2.spec +++ /dev/null @@ -1,35 +0,0 @@ -@ stdcall CsrAddStaticServerThread(ptr ptr long) -@ stdcall CsrCallServerFromServer(ptr ptr) -@ stdcall CsrConnectToUser() -@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr) -@ stdcall CsrCreateRemoteThread(ptr ptr) -@ stdcall CsrCreateThread(ptr ptr ptr long) -@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr) -@ stdcall CsrDebugProcess(ptr) -@ stdcall CsrDebugProcessStop(ptr) -@ stdcall CsrDereferenceProcess(ptr) -@ stdcall CsrDereferenceThread(ptr) -@ stdcall CsrDereferenceWait(ptr) -@ stdcall CsrDestroyProcess(ptr long) -@ stdcall CsrDestroyThread(ptr) -@ stdcall CsrExecServerThread(ptr long) -@ stdcall CsrGetProcessLuid(ptr ptr) -@ stdcall CsrImpersonateClient(ptr) -@ stdcall CsrLockProcessByClientId(ptr ptr) -@ stdcall CsrLockThreadByClientId(ptr ptr) -@ stdcall CsrMoveSatisfiedWait(ptr ptr) -@ stdcall CsrNotifyWait(ptr long ptr ptr) -@ stdcall CsrPopulateDosDevices() -@ stdcall CsrQueryApiPort() -@ stdcall CsrReferenceThread(ptr) -@ stdcall CsrRevertToSelf() -@ stdcall CsrServerInitialization(long ptr) -@ stdcall CsrSetBackgroundPriority(ptr) -@ stdcall CsrSetCallingSpooler(long) -@ stdcall CsrSetForegroundPriority(ptr) -@ stdcall CsrShutdownProcesses(ptr long) -@ stdcall CsrUnhandledExceptionFilter(ptr) -@ stdcall CsrUnlockProcess(ptr) -@ stdcall CsrUnlockThread(ptr) -@ stdcall CsrValidateMessageBuffer(ptr ptr long long) -@ stdcall CsrValidateMessageString(ptr ptr) diff --git a/subsystems/csr/csrsrv/init.c b/subsystems/csr/csrsrv/init.c deleted file mode 100644 index eee4f3d28d6..00000000000 --- a/subsystems/csr/csrsrv/init.c +++ /dev/null @@ -1,988 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System - * FILE: subsys/csr/csrsrv/init.c - * PURPOSE: CSR Server DLL Initialization - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES ******************************************************************/ - -#include "srv.h" - -#define NDEBUG -#include - -/* DATA **********************************************************************/ - -HANDLE CsrObjectDirectory; -ULONG SessionId; -BOOLEAN CsrProfileControl; -UNICODE_STRING CsrDirectoryName; -HANDLE CsrHeap; -HANDLE BNOLinksDirectory; -HANDLE SessionObjectDirectory; -HANDLE DosDevicesDirectory; -HANDLE CsrInitializationEvent; -SYSTEM_BASIC_INFORMATION CsrNtSysInfo; -ULONG CsrDebug; - -/* PRIVATE FUNCTIONS *********************************************************/ - -/*++ - * @name CsrParseServerCommandLine - * - * The CsrParseServerCommandLine routine parses the CSRSS command-line in the - * registry and performs operations for each entry found. - * - * @param ArgumentCount - * Number of arguments on the command line. - * - * @param Arguments - * Array of arguments. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -FASTCALL -CsrParseServerCommandLine(IN ULONG ArgumentCount, - IN PCHAR Arguments[]) -{ - NTSTATUS Status; - PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString; - ULONG i, DllIndex; - ANSI_STRING AnsiString; - OBJECT_ATTRIBUTES ObjectAttributes; - - /* Set the Defaults */ - CsrTotalPerProcessDataLength = 0; - CsrObjectDirectory = 0; - CsrMaxApiRequestThreads = 16; - - /* Save our Session ID, and create a Directory for it */ - SessionId = NtCurrentPeb()->SessionId; - Status = CsrCreateSessionObjectDirectory(SessionId); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n", - Status); - - /* It's not fatal if the session ID isn't zero */ - if (SessionId) return Status; - ASSERT(NT_SUCCESS(Status)); - } - - /* Loop through every argument */ - for (i = 1; i < ArgumentCount; i++) - { - /* Split Name and Value */ - ParameterName = Arguments[i]; - ParameterValue = NULL; - ParameterValue = strchr(ParameterName, '='); - if (ParameterValue) *ParameterValue++ = ANSI_NULL; - DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue); - - /* Check for Object Directory */ - if (!_stricmp(ParameterName, "ObjectDirectory")) - { - /* 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 | 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")) - { - /* Ignored */ - } - else if (!_stricmp(ParameterName, "MaxRequestThreads")) - { - Status = RtlCharToInteger(ParameterValue, - 0, - &CsrMaxApiRequestThreads); - } - else if (!_stricmp(ParameterName, "RequestThreads")) - { - /* Ignored */ - Status = STATUS_SUCCESS; - } - else if (!_stricmp(ParameterName, "ProfileControl")) - { - /* 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")) - { - /* 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 */ - } - else - { - /* Invalid parameter on the command line */ - Status = STATUS_INVALID_PARAMETER; - } - } - - /* Return status */ - return Status; -} - -/*++ - * @name CsrCreateLocalSystemSD - * - * The CsrCreateLocalSystemSD routine creates a Security Descriptor for - * the local account with PORT_ALL_ACCESS. - * - * @param LocalSystemSd - * Pointer to a pointer to the security descriptor to create. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd) -{ - SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY}; - PSID SystemSid; - ULONG Length; - PSECURITY_DESCRIPTOR SystemSd; - PACL Dacl; - NTSTATUS Status; - - /* Initialize the System SID */ - RtlAllocateAndInitializeSid(&NtSidAuthority, 1, - SECURITY_LOCAL_SYSTEM_RID, - 0, 0, 0, 0, 0, 0, 0, - &SystemSid); - - /* Get the length of the SID */ - Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); - - /* Allocate a buffer for the Security Descriptor, with SID and DACL */ - SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length); - - /* Set the pointer to the DACL */ - Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH); - - /* Now create the SD itself */ - Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - RtlFreeHeap(CsrHeap, 0, SystemSd); - return Status; - } - - /* Create the DACL for it*/ - RtlCreateAcl(Dacl, Length, ACL_REVISION2); - - /* Create the ACE */ - Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - RtlFreeHeap(CsrHeap, 0, SystemSd); - return Status; - } - - /* Clear the DACL in the SD */ - Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - RtlFreeHeap(CsrHeap, 0, SystemSd); - return Status; - } - - /* Free the SID and return*/ - RtlFreeSid(SystemSid); - *LocalSystemSd = SystemSd; - return Status; -} - -/*++ - * @name GetDosDevicesProtection - * - * The GetDosDevicesProtection creates a security descriptor for the DOS Devices - * Object Directory. - * - * @param DosDevicesSd - * Pointer to the Security Descriptor to return. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks Depending on the DOS Devices Protection Mode (set in the registry), - * regular users may or may not have full access to the directory. - * - *--*/ -NTSTATUS -NTAPI -GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd) -{ - SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; - SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY}; - SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY}; - PSID WorldSid, CreatorSid, AdminSid, SystemSid; - UCHAR KeyValueBuffer[0x40]; - PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo; - UNICODE_STRING KeyName; - ULONG ProtectionMode = 0; - OBJECT_ATTRIBUTES ObjectAttributes; - PACL Dacl; - PACCESS_ALLOWED_ACE Ace; - HANDLE hKey; - NTSTATUS Status; - ULONG ResultLength, SidLength, AclLength; - - /* Create the SD */ - Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION); - ASSERT(NT_SUCCESS(Status)); - - /* Initialize the System SID */ - Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1, - SECURITY_LOCAL_SYSTEM_RID, - 0, 0, 0, 0, 0, 0, 0, - &SystemSid); - ASSERT(NT_SUCCESS(Status)); - - /* Initialize the World SID */ - Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1, - SECURITY_WORLD_RID, - 0, 0, 0, 0, 0, 0, 0, - &WorldSid); - ASSERT(NT_SUCCESS(Status)); - - /* Initialize the Admin SID */ - Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, - &AdminSid); - ASSERT(NT_SUCCESS(Status)); - - /* Initialize the Creator SID */ - Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1, - SECURITY_CREATOR_OWNER_RID, - 0, 0, 0, 0, 0, 0, 0, - &CreatorSid); - ASSERT(NT_SUCCESS(Status)); - - /* Open the Session Manager Key */ - RtlInitUnicodeString(&KeyName, SM_REG_KEY); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes); - if (NT_SUCCESS(Status)) - { - /* Read the key value */ - RtlInitUnicodeString(&KeyName, L"ProtectionMode"); - Status = NtQueryValueKey(hKey, - &KeyName, - KeyValuePartialInformation, - KeyValueBuffer, - sizeof(KeyValueBuffer), - &ResultLength); - - /* Make sure it's what we expect it to be */ - KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer; - if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) && - (*(PULONG)KeyValuePartialInfo->Data)) - { - /* Save the Protection Mode */ - ProtectionMode = *(PULONG)KeyValuePartialInfo->Data; - } - - /* Close the handle */ - NtClose(hKey); - } - - /* Check the Protection Mode */ - if (ProtectionMode & 3) - { - /* 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, AclLength); - ASSERT(Dacl != NULL); - - /* Build the ACL and add 3 ACEs */ - Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); - ASSERT(NT_SUCCESS(Status)); - Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); - ASSERT(NT_SUCCESS(Status)); - Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid); - ASSERT(NT_SUCCESS(Status)); - Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid); - ASSERT(NT_SUCCESS(Status)); - - /* Edit the ACEs to make them inheritable */ - Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace); - ASSERT(NT_SUCCESS(Status)); - Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; - Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace); - ASSERT(NT_SUCCESS(Status)); - Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; - Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); - ASSERT(NT_SUCCESS(Status)); - Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; - - /* Set this DACL with the SD */ - Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); - ASSERT(NT_SUCCESS(Status)); - goto Quickie; - } - 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, AclLength); - ASSERT(Dacl != NULL); - - /* Build the ACL and add 3 ACEs */ - Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); - ASSERT(NT_SUCCESS(Status)); - Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid); - ASSERT(NT_SUCCESS(Status)); - Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); - ASSERT(NT_SUCCESS(Status)); - Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid); - ASSERT(NT_SUCCESS(Status)); - - /* Edit the last ACE to make it inheritable */ - Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); - ASSERT(NT_SUCCESS(Status)); - Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; - - /* Set this DACL with the SD */ - Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); - ASSERT(NT_SUCCESS(Status)); - goto Quickie; - } - -/* FIXME: failure cases! Fail: */ - /* Free the memory */ - RtlFreeHeap(CsrHeap, 0, Dacl); - -/* FIXME: semi-failure cases! Quickie: */ -Quickie: - /* Free the SIDs */ - RtlFreeSid(SystemSid); - RtlFreeSid(WorldSid); - RtlFreeSid(AdminSid); - RtlFreeSid(CreatorSid); - - /* Return */ - return Status; -} - -/*++ - * @name FreeDosDevicesProtection - * - * The FreeDosDevicesProtection frees the security descriptor that was created - * by GetDosDevicesProtection - * - * @param DosDevicesSd - * Pointer to the security descriptor to free. - - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -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); - ASSERT(NT_SUCCESS(Status)); - ASSERT(Present); - ASSERT(Dacl != NULL); - - /* Free it */ - if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl); -} - -/*++ - * @name CsrCreateSessionObjectDirectory - * - * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects, - * Session and Dos Devices directories for the specified session. - * - * @param Session - * Session ID for which to create the directories. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrCreateSessionObjectDirectory(IN ULONG Session) -{ - WCHAR SessionBuffer[512], BnoBuffer[512]; - UNICODE_STRING SessionString, BnoString; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE BnoHandle; - SECURITY_DESCRIPTOR DosDevicesSd; - NTSTATUS Status; - - /* Generate the Session BNOLINKS Directory name */ - swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT); - RtlInitUnicodeString(&SessionString, SessionBuffer); - - /* Create it */ - InitializeObjectAttributes(&ObjectAttributes, - &SessionString, - OBJ_OPENIF | OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = NtCreateDirectoryObject(&BNOLinksDirectory, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: NtCreateDirectoryObject failed in " - "CsrCreateSessionObjectDirectory - status = %lx\n", Status); - return Status; - } - - /* Now add the Session ID */ - swprintf(SessionBuffer, L"%ld", Session); - RtlInitUnicodeString(&SessionString, SessionBuffer); - - /* Check if this is the first Session */ - if (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 */ - RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects"); - } - - /* Create the symlink */ - InitializeObjectAttributes(&ObjectAttributes, - &SessionString, - OBJ_OPENIF | OBJ_CASE_INSENSITIVE, - BNOLinksDirectory, - NULL); - Status = NtCreateSymbolicLinkObject(&BnoHandle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes, - &BnoString); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in " - "CsrCreateSessionObjectDirectory - status = %lx\n", Status); - return Status; - } - - /* Create the \DosDevices Security Descriptor */ - 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); - - /* Create the directory */ - InitializeObjectAttributes(&ObjectAttributes, - &SessionString, - OBJ_OPENIF | OBJ_CASE_INSENSITIVE, - 0, - &DosDevicesSd); - Status = NtCreateDirectoryObject(&SessionObjectDirectory, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: NtCreateDirectoryObject failed in " - "CsrCreateSessionObjectDirectory - status = %lx\n", Status); - FreeDosDevicesProtection(&DosDevicesSd); - return Status; - } - - /* Next, create a directory for this session's DOS Devices */ - RtlInitUnicodeString(&SessionString, L"DosDevices"); - InitializeObjectAttributes(&ObjectAttributes, - &SessionString, - OBJ_CASE_INSENSITIVE, - SessionObjectDirectory, - &DosDevicesSd); - Status = NtCreateDirectoryObject(&DosDevicesDirectory, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSS: NtCreateDirectoryObject failed in " - "CsrCreateSessionObjectDirectory - status = %lx\n", Status); - } - - /* Release the Security Descriptor */ - FreeDosDevicesProtection(&DosDevicesSd); - - /* Return */ - return Status; -} - -/*++ - * @name CsrSetProcessSecurity - * - * The CsrSetProcessSecurity routine protects access to the CSRSS process - * from unauthorized tampering. - * - * @param None. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrSetProcessSecurity(VOID) -{ - NTSTATUS Status; - HANDLE hToken, hProcess = NtCurrentProcess(); - ULONG ReturnLength, Length; - PTOKEN_USER TokenInfo = NULL; - PSECURITY_DESCRIPTOR ProcSd = NULL; - PACL Dacl; - PSID UserSid; - - /* Open our token */ - Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken); - if (!NT_SUCCESS(Status)) goto Quickie; - - /* Get the Token User Length */ - NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length); - - /* Allocate space for it */ - TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length); - if (!TokenInfo) - { - Status = STATUS_NO_MEMORY; - goto Quickie; - } - - /* Now query the data */ - Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length); - NtClose(hToken); - if (!NT_SUCCESS(Status)) goto Quickie; - - /* Now check the SID Length */ - UserSid = TokenInfo->User.Sid; - ReturnLength = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); - - /* Allocate a buffer for the Security Descriptor, with SID and DACL */ - ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length); - if (!ProcSd) - { - 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, Length, ACL_REVISION2); - - /* Create the ACE */ - Status = RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - PROCESS_VM_READ | PROCESS_VM_WRITE | - PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE | - PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME | - PROCESS_QUERY_INFORMATION | READ_CONTROL, - UserSid); - if (!NT_SUCCESS(Status)) goto Quickie; - - /* Clear the DACL in the SD */ - Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE); - if (!NT_SUCCESS(Status)) goto Quickie; - - /* Write the SD into the Process */ - Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd); - - /* Free the memory and return */ -Quickie: - if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd); - RtlFreeHeap(CsrHeap, 0, TokenInfo); - return Status; -} - -/*++ - * @name CsrSetDirectorySecurity - * - * The CsrSetDirectorySecurity routine sets the security descriptor for the - * specified Object Directory. - * - * @param ObjectDirectory - * Handle fo the Object Directory to protect. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrSetDirectorySecurity(IN HANDLE ObjectDirectory) -{ - /* FIXME: Implement */ - return STATUS_SUCCESS; -} - -/* PUBLIC FUNCTIONS **********************************************************/ - -/*++ - * @name CsrServerInitialization - * @implemented NT4 - * - * The CsrServerInitialization routine is the native (not Server) entrypoint - * of this Server DLL. It serves as the entrypoint for csrss. - * - * @param ArgumentCount - * Number of arguments on the command line. - * - * @param Arguments - * Array of arguments from the command line. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrServerInitialization(IN ULONG ArgumentCount, - IN PCHAR Arguments[]) -{ - NTSTATUS Status = STATUS_SUCCESS; - ULONG i = 0; - PVOID ProcessData; - PCSR_SERVER_DLL ServerDll; - DPRINT("CSRSRV: %s called\n", __FUNCTION__); - - /* Create the Init Event */ - Status = NtCreateEvent(&CsrInitializationEvent, - EVENT_ALL_ACCESS, - 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 */ - Status = CsrSetProcessSecurity(); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n", - __FUNCTION__, Status); - return Status; - } - - /* Set up Session Support */ - Status = CsrInitializeNtSessionList(); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n", - __FUNCTION__, Status); - return Status; - } - - /* Set up Process Support */ - Status = CsrInitializeProcessStructure(); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n", - __FUNCTION__, Status); - return Status; - } - - /* Parse the command line */ - 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++) - { - /* Get the current Server */ - ServerDll = CsrLoadedServerDll[i]; - - /* Is it loaded, and does it have per process data? */ - if ((ServerDll) && (ServerDll->SizeOfProcessData)) - { - /* It does, give it part of our allocated heap */ - CsrRootProcess->ServerData[i] = ProcessData; - - /* Move to the next heap position */ - ProcessData = (PVOID)((ULONG_PTR)ProcessData + - ServerDll->SizeOfProcessData); - } - else - { - /* Nothing for this Server DLL */ - CsrRootProcess->ServerData[i] = NULL; - } - } - - /* Now initialize the Root Process manually as well */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Get the current Server */ - ServerDll = CsrLoadedServerDll[i]; - - /* Is it loaded, and does it a callback for new processes? */ - if ((ServerDll) && (ServerDll->NewProcessCallback)) - { - /* Call the callback */ - ServerDll->NewProcessCallback(NULL, CsrRootProcess); - } - } - - /* Now initialize our API Port */ - Status = CsrApiPortInitialize(); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n", - __FUNCTION__, Status); - return Status; - } - - /* Initialize the API Port for SM communication */ - Status = CsrSbApiPortInitialize(); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n", - __FUNCTION__, Status); - return Status; - } - - /* We're all set! Connect to SM! */ - Status = SmConnectToSm(&CsrSbApiPortName, - CsrSbApiPort, - IMAGE_SUBSYSTEM_WINDOWS_GUI, - &CsrSmApiPort); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n", - __FUNCTION__, Status); - return Status; - } - - /* Finito! Signal the event */ - 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 */ - 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 - * @unimplemented NT5.1 - * - * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel - * to populate the Dos Devices Object Directory for the session. - * - * @param None. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrPopulateDosDevices(VOID) -{ - DPRINT1("Deprecated API\n"); - return; -} - -BOOL -NTAPI -DllMain(IN HANDLE hDll, - IN DWORD dwReason, - IN LPVOID lpReserved) -{ - /* We don't do much */ - UNREFERENCED_PARAMETER(hDll); - UNREFERENCED_PARAMETER(dwReason); - UNREFERENCED_PARAMETER(lpReserved); - return TRUE; -} - -/* EOF */ diff --git a/subsystems/csr/csrsrv/process.c b/subsystems/csr/csrsrv/process.c deleted file mode 100644 index 9bf455db7c4..00000000000 --- a/subsystems/csr/csrsrv/process.c +++ /dev/null @@ -1,1342 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System - * FILE: subsys/csr/csrsrv/process.c - * PURPOSE: CSR Server DLL Process Implementation - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES ******************************************************************/ - -#include "srv.h" - -#define NDEBUG -#include - -/* DATA **********************************************************************/ - -PCSR_PROCESS CsrRootProcess = NULL; -RTL_CRITICAL_SECTION CsrProcessLock; -ULONG CsrProcessSequenceCount = 5; -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 - * - * The CsrAllocateProcess routine allocates a new CSR Process object. - * - * @return Pointer to the newly allocated CSR Process. - * - * @remarks None. - * - *--*/ -PCSR_PROCESS -NTAPI -CsrAllocateProcess(VOID) -{ - PCSR_PROCESS CsrProcess; - ULONG TotalSize; - - /* Calculate the amount of memory this should take */ - TotalSize = sizeof(CSR_PROCESS) + - (CSR_SERVER_DLL_MAX * sizeof(PVOID)) + - CsrTotalPerProcessDataLength; - - /* Allocate a Process */ - CsrProcess = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, TotalSize); - if (!CsrProcess) return NULL; - - /* Handle the Sequence Number and protect against overflow */ - CsrProcess->SequenceNumber = CsrProcessSequenceCount++; - if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5; - - /* Increase the reference count */ - CsrProcess->ReferenceCount++; - - /* Initialize the Thread List */ - InitializeListHead(&CsrProcess->ThreadList); - - /* Return the Process */ - return CsrProcess; -} - -/*++ - * @name CsrServerInitialization - * @implemented NT4 - * - * The CsrInitializeProcessStructure routine sets up support for CSR Processes - * and CSR Threads. - * - * @param None. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -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(); - if (!CsrRootProcess) return STATUS_NO_MEMORY; - - /* Set up the minimal information for it */ - InitializeListHead(&CsrRootProcess->ListLink); - CsrRootProcess->ProcessHandle = (HANDLE)-1; - CsrRootProcess->ClientId = NtCurrentTeb()->ClientId; - - /* Initialize the Thread Hash List */ - for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]); - - /* Initialize the Wait Lock */ - return RtlInitializeCriticalSection(&CsrWaitListsLock); -} - -/*++ - * @name CsrDeallocateProcess - * - * The CsrDeallocateProcess frees the memory associated with a CSR Process. - * - * @param CsrProcess - * Pointer to the CSR Process to be freed. - * - * @return None. - * - * @remarks Do not call this routine. It is reserved for the internal - * thread management routines when a CSR Process has been cleanly - * dereferenced and killed. - * - *--*/ -VOID -NTAPI -CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess) -{ - /* Free the process object from the heap */ - RtlFreeHeap(CsrHeap, 0, CsrProcess); -} - -/*++ - * @name CsrInsertProcess - * - * The CsrInsertProcess routine inserts a CSR Process into the Process List - * and notifies Server DLLs of the creation of a new CSR Process. - * - * @param Parent - * Optional pointer to the CSR Process creating this CSR Process. - * - * @param CurrentProcess - * Optional pointer to the current CSR Process. - * - * @param CsrProcess - * Pointer to the CSR Process which is to be inserted. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, - IN PCSR_PROCESS CurrentProcess OPTIONAL, - IN PCSR_PROCESS CsrProcess) -{ - PCSR_SERVER_DLL ServerDll; - ULONG i; - ASSERT(ProcessStructureListLocked()); - - /* Set the parent */ - CsrProcess->Parent = Parent; - - /* Insert it into the Root List */ - InsertTailList(&CsrRootProcess->ListLink, &CsrProcess->ListLink); - - /* Notify the Server DLLs */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Get the current Server DLL */ - ServerDll = CsrLoadedServerDll[i]; - - /* Make sure it's valid and that it has callback */ - if ((ServerDll) && (ServerDll->NewProcessCallback)) - { - ServerDll->NewProcessCallback(CurrentProcess, CsrProcess); - } - } -} - -/*++ - * @name CsrLockedDereferenceProcess - * - * The CsrLockedDereferenceProcess dereferences a CSR Process while the - * Process Lock is already being held. - * - * @param CsrProcess - * Pointer to the CSR Process to be dereferenced. - * - * @return None. - * - * @remarks This routine will return with the Process Lock held. - * - *--*/ -VOID -NTAPI -CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess) -{ - LONG LockCount; - - /* Decrease reference count */ - LockCount = --CsrProcess->ReferenceCount; - ASSERT(LockCount >= 0); - if (!LockCount) - { - /* Call the generic cleanup code */ - 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 - * - * The CsrRemoveProcess function undoes a CsrInsertProcess operation and - * removes the CSR Process from the Process List and notifies Server DLLs - * of this removal. - * - * @param CsrProcess - * Pointer to the CSR Process to remove. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrRemoveProcess(IN PCSR_PROCESS CsrProcess) -{ - PCSR_SERVER_DLL ServerDll; - ULONG i; - ASSERT(ProcessStructureListLocked()); - - /* Remove us from the Process List */ - RemoveEntryList(&CsrProcess->ListLink); - - /* Release the lock */ - CsrReleaseProcessLock(); - - /* Loop every Server DLL */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Get the Server DLL */ - ServerDll = CsrLoadedServerDll[i]; - - /* Check if it's valid and if it has a Disconnect Callback */ - if ((ServerDll) && (ServerDll->DisconnectCallback)) - { - /* Call it */ - ServerDll->DisconnectCallback(CsrProcess); - } - } -} - -/*++ - * @name CsrProcessRefcountZero - * - * The CsrProcessRefcountZero routine is executed when a CSR Process has lost - * all its active references. It removes and de-allocates the CSR Process. - * - * @param CsrProcess - * Pointer to the CSR Process that is to be deleted. - * - * @return None. - * - * @remarks Do not call this routine. It is reserved for the internal - * thread management routines when a CSR Process has lost all - * its references. - * - * This routine is called with the Process Lock held. - * - *--*/ -VOID -NTAPI -CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess) -{ - /* Remove the Process from the list */ - CsrRemoveProcess(CsrProcess); - - /* Check if there's a session */ - if (CsrProcess->NtSession) - { - /* Dereference the Session */ - CsrDereferenceNtSession(CsrProcess->NtSession, 0); - } - - /* Close the Client Port if there is one */ - if (CsrProcess->ClientPort) NtClose(CsrProcess->ClientPort); - - /* Close the process handle */ - NtClose(CsrProcess->ProcessHandle); - - /* Free the Proces Object */ - CsrDeallocateProcess(CsrProcess); -} - -/*++ - * @name CsrpSetToNormalPriority - * - * The CsrpSetToNormalPriority routine sets the current NT Process' - * priority to the normal priority for CSR Processes. - * - * @param None. - * - * @return None. - * - * @remarks The "Normal" Priority corresponds to the Normal Forground - * Priority (9) plus a boost of 4. - * - *--*/ -VOID -NTAPI -CsrpSetToNormalPriority(VOID) -{ - KPRIORITY BasePriority = (8 + 1) + 4; - - /* Set the Priority */ - NtSetInformationProcess(NtCurrentProcess(), - ProcessBasePriority, - &BasePriority, - sizeof(KPRIORITY)); -} - -/*++ - * @name CsrpSetToShutdownPriority - * - * 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. - * - * @param None. - * - * @return None. - * - * @remarks The "Shutdown" Priority corresponds to the Normal Forground - * Priority (9) plus a boost of 6. - * - *--*/ -VOID -NTAPI -CsrpSetToShutdownPriority(VOID) -{ - KPRIORITY SetBasePriority = (8 + 1) + 6; - BOOLEAN Old; - - /* Get the shutdown privilege */ - if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, - TRUE, - FALSE, - &Old))) - { - /* Set the Priority */ - NtSetInformationProcess(NtCurrentProcess(), - ProcessBasePriority, - &SetBasePriority, - sizeof(KPRIORITY)); - } -} - -/*++ - * @name FindProcessForShutdown - * - * The FindProcessForShutdown routine returns a CSR Process which is ready - * to be shutdown, and sets the appropriate shutdown flags for it. - * - * @param CallerLuid - * Pointer to the LUID of the CSR Process calling this routine. - * - * @return Pointer to a CSR Process which is ready to be shutdown. - * - * @remarks None. - * - *--*/ -PCSR_PROCESS -NTAPI -FindProcessForShutdown(IN PLUID CallerLuid) -{ - PLIST_ENTRY NextEntry; - LUID ProcessLuid; - NTSTATUS Status; - LUID SystemLuid = SYSTEM_LUID; - PCSR_PROCESS CsrProcess; - PCSR_THREAD CsrThread; - PCSR_PROCESS ReturnCsrProcess = NULL; - ULONG Level = 0; - - /* Set the List Pointers */ - NextEntry = CsrRootProcess->ListLink.Flink; - while (NextEntry != &CsrRootProcess->ListLink) - { - /* Get the process */ - CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); - - /* Move to the next entry */ - NextEntry = NextEntry->Flink; - - /* Skip this process if it's already been processed*/ - if (CsrProcess->Flags & CsrProcessSkipShutdown) continue; - - /* Get the LUID of this Process */ - Status = CsrGetProcessLuid(CsrProcess->ProcessHandle, &ProcessLuid); - - /* Check if we didn't get access to the LUID */ - if (Status == STATUS_ACCESS_DENIED) - { - /* Check if we have any threads */ - if (CsrProcess->ThreadCount) - { - /* Impersonate one of the threads and retry */ - CsrThread = CONTAINING_RECORD(CsrProcess->ThreadList.Flink, - CSR_THREAD, - Link); - CsrImpersonateClient(CsrThread); - Status = CsrGetProcessLuid(NULL, &ProcessLuid); - CsrRevertToSelf(); - } - } - - if (!NT_SUCCESS(Status)) - { - /* We didn't have access, so skip it */ - CsrProcess->Flags |= CsrProcessSkipShutdown; - continue; - } - - /* Check if this is the System LUID */ - if (RtlEqualLuid(&ProcessLuid, &SystemLuid)) - { - /* Mark this process */ - CsrProcess->ShutdownFlags |= CsrShutdownSystem; - } - 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) || !(ReturnCsrProcess)) - { - /* Update the level */ - Level = CsrProcess->ShutdownLevel; - - /* Set the final process */ - ReturnCsrProcess = CsrProcess; - } - } - - /* Check if we found a process */ - if (ReturnCsrProcess) - { - /* Skip this one next time */ - ReturnCsrProcess->Flags |= CsrProcessSkipShutdown; - } - - return ReturnCsrProcess; -} - -/* PUBLIC FUNCTIONS ***********************************************************/ - -/*++ - * @name CsrCreateProcess - * @implemented NT4 - * - * Do nothing for 500ms. - * - * @param ArgumentCount - * Description of the parameter. Wrapped to more lines on ~70th - * column. - * - * @param Arguments - * Description of the parameter. Wrapped to more lines on ~70th - * column. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrCreateProcess(IN HANDLE hProcess, - IN HANDLE hThread, - IN PCLIENT_ID ClientId, - IN PCSR_NT_SESSION NtSession, - IN ULONG Flags, - IN PCLIENT_ID DebugCid) -{ - PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; - CLIENT_ID CurrentCid; - PCSR_PROCESS CurrentProcess; - PVOID ProcessData; - ULONG i; - PCSR_PROCESS CsrProcess; - NTSTATUS Status; - PCSR_THREAD CsrThread; - KERNEL_USER_TIMES KernelTimes; - - /* Get the current CID and lock Processes */ - CurrentCid = CurrentThread->ClientId; - CsrAcquireProcessLock(); - - /* Get the current CSR Thread */ - CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid); - if (!CurrentThread) - { - /* We've failed to locate the thread */ - CsrReleaseProcessLock(); - return STATUS_THREAD_IS_TERMINATING; - } - - /* Allocate a new Process Object */ - CsrProcess = CsrAllocateProcess(); - if (!CsrProcess) - { - /* Couldn't allocate Process */ - CsrReleaseProcessLock(); - return STATUS_NO_MEMORY; - } - - /* Inherit the Process Data */ - CurrentProcess = CurrentThread->Process; - ProcessData = &CurrentProcess->ServerData[CSR_SERVER_DLL_MAX]; - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Check if the DLL is Loaded and has Per Process Data */ - if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData) - { - /* Set the pointer */ - CsrProcess->ServerData[i] = ProcessData; - - /* Copy the Data */ - RtlMoveMemory(ProcessData, - CurrentProcess->ServerData[i], - CsrLoadedServerDll[i]->SizeOfProcessData); - - /* Update next data pointer */ - ProcessData = (PVOID)((ULONG_PTR)ProcessData + - CsrLoadedServerDll[i]->SizeOfProcessData); - } - else - { - /* No data for this Server */ - CsrProcess->ServerData[i] = NULL; - } - } - - /* Set the Exception port to us */ - Status = NtSetInformationProcess(hProcess, - ProcessExceptionPort, - &CsrApiPort, - sizeof(HANDLE)); - if (!NT_SUCCESS(Status)) - { - /* Failed */ - CsrDeallocateProcess(CsrProcess); - CsrReleaseProcessLock(); - return STATUS_NO_MEMORY; - } - - /* If Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */ - if (!(Flags & CsrProcessCreateNewGroup)) - { - /* Create new data */ - CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess); - CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber; - } - else - { - /* Copy it from the current process */ - CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId; - CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence; - } - - /* Check if this is a console process */ - if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp; - - /* Mask out non-debug flags */ - Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags); - - /* Check if every process will be debugged */ - if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren)) - { - /* Pass it on to the current process */ - CsrProcess->DebugFlags = CsrDebugProcessChildren; - CsrProcess->DebugCid = CurrentProcess->DebugCid; - } - - /* Check if Debugging was used on this process */ - if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid)) - { - /* Save the debug flag used */ - CsrProcess->DebugFlags = Flags; - - /* Save the CID */ - CsrProcess->DebugCid = *DebugCid; - } - - /* Check if we debugging is enabled */ - if (CsrProcess->DebugFlags) - { - /* Set the Debug Port to us */ - Status = NtSetInformationProcess(hProcess, - ProcessDebugPort, - &CsrApiPort, - sizeof(HANDLE)); - ASSERT(NT_SUCCESS(Status)); - if (!NT_SUCCESS(Status)) - { - /* Failed */ - CsrDeallocateProcess(CsrProcess); - CsrReleaseProcessLock(); - return STATUS_NO_MEMORY; - } - } - - /* Get the Thread Create Time */ - Status = NtQueryInformationThread(hThread, - ThreadTimes, - (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) - { - /* Failed */ - CsrDeallocateProcess(CsrProcess); - CsrReleaseProcessLock(); - return STATUS_NO_MEMORY; - } - - /* Save the data we have */ - CsrThread->CreateTime = KernelTimes.CreateTime; - CsrThread->ClientId = *ClientId; - CsrThread->ThreadHandle = hThread; - ProtectHandle(hThread); - CsrThread->Flags = 0; - - /* Insert the Thread into the Process */ - CsrInsertThread(CsrProcess, CsrThread); - - /* Reference the session */ - CsrReferenceNtSession(NtSession); - CsrProcess->NtSession = NtSession; - - /* Setup Process Data */ - CsrProcess->ClientId = *ClientId; - CsrProcess->ProcessHandle = hProcess; - CsrProcess->ShutdownLevel = 0x280; - - /* Set the Priority to Background */ - CsrSetBackgroundPriority(CsrProcess); - - /* Insert the Process */ - CsrInsertProcess(NULL, CurrentProcess, CsrProcess); - - /* Release lock and return */ - CsrReleaseProcessLock(); - return Status; -} - -/*++ - * @name CsrDebugProcess - * @implemented NT4 - * - * The CsrDebugProcess routine is deprecated in NT 5.1 and higher. It is - * exported only for compatibility with older CSR Server DLLs. - * - * @param CsrProcess - * Deprecated. - * - * @return Deprecated - * - * @remarks Deprecated. - * - *--*/ -NTSTATUS -NTAPI -CsrDebugProcess(IN PCSR_PROCESS CsrProcess) -{ - /* CSR does not handle debugging anymore */ - DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess); - return STATUS_UNSUCCESSFUL; -} - -/*++ - * @name CsrServerInitialization - * @implemented NT4 - * - * The CsrDebugProcessStop routine is deprecated in NT 5.1 and higher. It is - * exported only for compatibility with older CSR Server DLLs. - * - * @param CsrProcess - * Deprecated. - * - * @return Deprecated - * - * @remarks Deprecated. - * - *--*/ -NTSTATUS -NTAPI -CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess) -{ - /* CSR does not handle debugging anymore */ - DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess); - return STATUS_UNSUCCESSFUL; -} - -/*++ - * @name CsrDereferenceProcess - * @implemented NT4 - * - * The CsrDereferenceProcess routine removes a reference from a CSR Process. - * - * @param CsrThread - * Pointer to the CSR Process to dereference. - * - * @return None. - * - * @remarks If the reference count has reached zero (ie: the CSR Process has - * no more active references), it will be deleted. - * - *--*/ -VOID -NTAPI -CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess) -{ - LONG LockCount; - - /* Acquire process lock */ - CsrAcquireProcessLock(); - - /* Decrease reference count */ - LockCount = --CsrProcess->ReferenceCount; - ASSERT(LockCount >= 0); - if (!LockCount) - { - /* Call the generic cleanup code */ - CsrProcessRefcountZero(CsrProcess); - } - else - { - /* Just release the lock */ - CsrReleaseProcessLock(); - } -} - -/*++ - * @name CsrDestroyProcess - * @implemented NT4 - * - * 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. - * - * @param ExitStatus - * Unused. - * - * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING - * if the CSR Process is already terminating. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrDestroyProcess(IN PCLIENT_ID Cid, - IN NTSTATUS ExitStatus) -{ - PCSR_THREAD CsrThread; - PCSR_PROCESS CsrProcess; - CLIENT_ID ClientId = *Cid; - PLIST_ENTRY NextEntry; - - /* Acquire lock */ - CsrAcquireProcessLock(); - - /* Find the thread */ - CsrThread = CsrLocateThreadByClientId(&CsrProcess, &ClientId); - - /* Make sure we got one back, and that it's not already gone */ - if (!(CsrThread) || (CsrProcess->Flags & CsrProcessTerminating)) - { - /* Release the lock and return failure */ - CsrReleaseProcessLock(); - return STATUS_THREAD_IS_TERMINATING; - } - - /* Set the terminated flag */ - CsrProcess->Flags |= CsrProcessTerminating; - - /* Get the List Pointers */ - NextEntry = CsrProcess->ThreadList.Flink; - while (NextEntry != &CsrProcess->ThreadList) - { - /* Get the current thread entry */ - CsrThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); - - /* Make sure the thread isn't already dead */ - if (CsrThread->Flags & CsrThreadTerminated) - { - NextEntry = NextEntry->Flink; - continue; - } - - /* Set the Terminated flag */ - CsrThread->Flags |= CsrThreadTerminated; - - /* Acquire the Wait Lock */ - CsrAcquireWaitLock(); - - /* Do we have an active wait block? */ - if (CsrThread->WaitBlock) - { - /* Notify waiters of termination */ - CsrNotifyWaitBlock(CsrThread->WaitBlock, - NULL, - NULL, - NULL, - CsrProcessTerminating, - TRUE); - } - - /* Release the Wait Lock */ - CsrReleaseWaitLock(); - - /* Dereference the thread */ - CsrLockedDereferenceThread(CsrThread); - NextEntry = CsrProcess->ThreadList.Flink; - } - - /* Release the Process Lock and return success */ - CsrReleaseProcessLock(); - return STATUS_SUCCESS; -} - -/*++ - * @name CsrGetProcessLuid - * @implemented NT4 - * - * Do nothing for 500ms. - * - * @param hProcess - * Optional handle to the process whose LUID should be returned. - * - * @param Luid - * Pointer to a LUID Pointer which will receive the CSR Process' LUID - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks If hProcess is not supplied, then the current thread's token will - * be used. If that too is missing, then the current process' token - * will be used. - * - *--*/ -NTSTATUS -NTAPI -CsrGetProcessLuid(HANDLE hProcess OPTIONAL, - PLUID Luid) -{ - HANDLE hToken = NULL; - NTSTATUS Status; - ULONG Length; - PTOKEN_STATISTICS TokenStats; - - /* Check if we have a handle to a CSR Process */ - if (!hProcess) - { - /* We don't, so try opening the Thread's Token */ - Status = NtOpenThreadToken(NtCurrentThread(), - TOKEN_QUERY, - FALSE, - &hToken); - - /* Check for success */ - if (!NT_SUCCESS(Status)) - { - /* If we got some other failure, then return and quit */ - if (Status != STATUS_NO_TOKEN) return Status; - - /* We don't have a Thread Token, use a Process Token */ - hProcess = NtCurrentProcess(); - hToken = NULL; - } - } - - /* Check if we have a token by now */ - if (!hToken) - { - /* No token yet, so open the Process Token */ - Status = NtOpenProcessToken(hProcess, - TOKEN_QUERY, - &hToken); - if (!NT_SUCCESS(Status)) return Status; - } - - /* Now get the size we'll need for the Token Information */ - Status = NtQueryInformationToken(hToken, - TokenStatistics, - NULL, - 0, - &Length); - - /* Allocate memory for the Token Info */ - TokenStats = RtlAllocateHeap(CsrHeap, 0, Length); - if (!TokenStats) - { - /* Fail and close the token */ - NtClose(hToken); - return STATUS_NO_MEMORY; - } - - /* Now query the information */ - Status = NtQueryInformationToken(hToken, - TokenStatistics, - TokenStats, - Length, - &Length); - - /* Close the handle */ - NtClose(hToken); - - /* Check for success to return the LUID */ - if (NT_SUCCESS(Status)) *Luid = TokenStats->AuthenticationId; - - /* Free the query information */ - RtlFreeHeap(CsrHeap, 0, TokenStats); - - /* Return the Status */ - return Status; -} - -/*++ - * @name CsrLockProcessByClientId - * @implemented NT4 - * - * The CsrLockProcessByClientId routine locks the CSR Process corresponding - * to the given Process ID and optionally returns it. - * - * @param Pid - * Process ID corresponding to the CSR Process which will be locked. - * - * @param CsrProcess - * Optional pointer to a CSR Process pointer which will hold the - * CSR Process corresponding to the given Process ID. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks Locking a CSR Process is defined as acquiring an extra - * reference to it and returning with the Process Lock held. - * - *--*/ -NTSTATUS -NTAPI -CsrLockProcessByClientId(IN HANDLE Pid, - OUT PCSR_PROCESS *CsrProcess) -{ - PLIST_ENTRY NextEntry; - PCSR_PROCESS CurrentProcess = NULL; - NTSTATUS Status; - - /* Acquire the lock */ - CsrAcquireProcessLock(); - - /* Assume failure */ - ASSERT(CsrProcess != NULL); - *CsrProcess = NULL; - - /* Setup the List Pointers */ - NextEntry = &CsrRootProcess->ListLink; - do - { - /* Get the Process */ - CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); - - /* Check for PID Match */ - if (CurrentProcess->ClientId.UniqueProcess == Pid) - { - Status = STATUS_SUCCESS; - break; - } - - /* Next entry */ - NextEntry = NextEntry->Flink; - } while (NextEntry != &CsrRootProcess->ListLink); - - /* Check if we didn't find it in the list */ - if (!NT_SUCCESS(Status)) - { - /* Nothing found, release the lock */ - CsrReleaseProcessLock(); - } - else - { - /* Lock the found process and return it */ - CsrLockedReferenceProcess(CurrentProcess); - *CsrProcess = CurrentProcess; - } - - /* Return the result */ - return Status; -} - -/*++ - * @name CsrSetForegroundPriority - * @implemented NT4 - * - * The CsrSetForegroundPriority routine sets the priority for the given CSR - * Process as a Foreground priority. - * - * @param CsrProcess - * Pointer to the CSR Process whose priority will be modified. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess) -{ - PROCESS_PRIORITY_CLASS PriorityClass; - - /* Set the Foreground bit on */ - PriorityClass.Foreground = TRUE; - - /* Set the new Priority */ - NtSetInformationProcess(CsrProcess->ProcessHandle, - ProcessPriorityClass, - &PriorityClass, - sizeof(PriorityClass)); -} - -/*++ - * @name CsrSetBackgroundPriority - * @implemented NT4 - * - * The CsrSetBackgroundPriority routine sets the priority for the given CSR - * Process as a Background priority. - * - * @param CsrProcess - * Pointer to the CSR Process whose priority will be modified. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess) -{ - PROCESS_PRIORITY_CLASS PriorityClass; - - /* Set the Foreground bit off */ - PriorityClass.Foreground = FALSE; - - /* Set the new Priority */ - NtSetInformationProcess(CsrProcess->ProcessHandle, - ProcessPriorityClass, - &PriorityClass, - sizeof(PriorityClass)); -} - -/*++ - * @name CsrShutdownProcesses - * @implemented NT4 - * - * The CsrShutdownProcesses routine shuts down every CSR Process possible - * and calls each Server DLL's shutdown notification. - * - * @param CallerLuid - * Pointer to the LUID of the CSR Process that is ordering the - * shutdown. - * - * @param Flags - * Flags to send to the shutdown notification routine. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrShutdownProcesses(IN PLUID CallerLuid, - IN ULONG Flags) -{ - PLIST_ENTRY NextEntry; - PCSR_PROCESS CsrProcess; - NTSTATUS Status; - BOOLEAN FirstTry; - ULONG i; - PCSR_SERVER_DLL ServerDll; - ULONG Result = 0; /* Intentionally invalid enumeratee to silence compiler warning */ - - /* Acquire process lock */ - CsrAcquireProcessLock(); - - /* Add shutdown flag */ - CsrRootProcess->ShutdownFlags |= CsrShutdownSystem; - - /* Get the list pointers */ - NextEntry = CsrRootProcess->ListLink.Flink; - while (NextEntry != &CsrRootProcess->ListLink) - { - /* Get the Process */ - CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); - - /* Remove the skip flag, set shutdown flags to 0*/ - CsrProcess->Flags &= ~CsrProcessSkipShutdown; - CsrProcess->ShutdownFlags = 0; - - /* Move to the next */ - NextEntry = NextEntry->Flink; - } - - /* Set shudown Priority */ - CsrpSetToShutdownPriority(); - - /* Start looping */ - while (TRUE) - { - /* Find the next process to shutdown */ - CsrProcess = FindProcessForShutdown(CallerLuid); - if (!CsrProcess) break; - - /* Increase reference to process */ - CsrProcess->ReferenceCount++; - - FirstTry = TRUE; - while (TRUE) - { - /* Loop all the servers */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Get the current server */ - ServerDll = CsrLoadedServerDll[i]; - if ((ServerDll) && (ServerDll->ShutdownProcessCallback)) - { - /* Release the lock, make the callback, and acquire it back */ - CsrReleaseProcessLock(); - 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; - 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 */ - CsrpSetToNormalPriority(); - return Status; -} - -/*++ - * @name CsrUnlockProcess - * @implemented NT4 - * - * The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation. - * - * @param CsrProcess - * Pointer to a previously locked CSR Process. - * - * @return STATUS_SUCCESS. - * - * @remarks This routine must be called with the Process Lock held. - * - *--*/ -NTSTATUS -NTAPI -CsrUnlockProcess(IN PCSR_PROCESS CsrProcess) -{ - /* Dereference the process */ - CsrLockedDereferenceProcess(CsrProcess); - - /* Release the lock and return */ - CsrReleaseProcessLock(); - return STATUS_SUCCESS; -} - -/* EOF */ diff --git a/subsystems/csr/csrsrv/server.c b/subsystems/csr/csrsrv/server.c deleted file mode 100644 index 12100055981..00000000000 --- a/subsystems/csr/csrsrv/server.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System - * FILE: subsys/csr/csrsrv/server.c - * PURPOSE: CSR Server DLL Server Functions - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES ******************************************************************/ -#include "srv.h" - -#define NDEBUG -#include - -/* DATA **********************************************************************/ - -PCSR_API_ROUTINE CsrServerApiDispatchTable[5] = -{ - CsrSrvClientConnect, - CsrSrvUnusedFunction, - CsrSrvUnusedFunction, - CsrSrvIdentifyAlertableThread, - CsrSrvSetPriorityClass -}; - -BOOLEAN CsrServerApiServerValidTable[5] = -{ - TRUE, - FALSE, - TRUE, - TRUE, - TRUE -}; - -PCHAR CsrServerApiNameTable[5] = -{ - "ClientConnect", - "ThreadConnect", - "ProfileControl", - "IdentifyAlertableThread", - "SetPriorityClass" -}; - -PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]; -PVOID CsrSrvSharedSectionHeap; -PVOID CsrSrvSharedSectionBase; -PVOID *CsrSrvSharedStaticServerData; -ULONG CsrSrvSharedSectionSize; -HANDLE CsrSrvSharedSection; - -/* PRIVATE FUNCTIONS**********************************************************/ - -/*++ - * @name CsrLoadServerDll - * @implemented NT4 - * - * The CsrLoadServerDll routine loads a CSR Server DLL and calls its entrypoint - * - * @param DllString - * Pointer to the CSR Server DLL to load and call. - * - * @param EntryPoint - * Pointer to the name of the server's initialization function. If - * this parameter is NULL, the default ServerDllInitialize will be - * assumed. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrLoadServerDll(IN PCHAR DllString, - IN PCHAR EntryPoint OPTIONAL, - IN ULONG ServerId) -{ - NTSTATUS Status; - ANSI_STRING DllName; - 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; - - /* Check if it's already been loaded */ - 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; - } - - /* Allocate a CSR DLL Object */ - Size = sizeof(CSR_SERVER_DLL) + DllName.MaximumLength; - ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size); - if (!ServerDll) - { - if (hServerDll) LdrUnloadDll(hServerDll); - return STATUS_NO_MEMORY; - } - - /* Set up the Object */ - ServerDll->Length = Size; - ServerDll->SharedSection = CsrSrvSharedSectionHeap; - ServerDll->Event = CsrInitializationEvent; - ServerDll->Name.Length = DllName.Length; - ServerDll->Name.MaximumLength = DllName.MaximumLength; - ServerDll->Name.Buffer = (PCHAR)(ServerDll + 1); - if (DllName.Length) - { - strncpy(ServerDll->Name.Buffer, DllName.Buffer, DllName.Length); - } - ServerDll->ServerId = ServerId; - ServerDll->ServerHandle = hServerDll; - - /* Now get the entrypoint */ - if (hServerDll) - { - /* Initialize a string for the entrypoint, or use the default */ - RtlInitAnsiString(&EntryPointString, - !(EntryPoint) ? "ServerDllInitialization" : - EntryPoint); - - /* Get a pointer to it */ - Status = LdrGetProcedureAddress(hServerDll, - &EntryPointString, - 0, - (PVOID)&ServerDllInitProcedure); - } - else - { - /* No handle, so we are loading ourselves */ - ServerDllInitProcedure = CsrServerDllInitialization; - Status = STATUS_SUCCESS; - } - - /* Check if we got the pointer, and call it */ - if (NT_SUCCESS(Status)) - { - /* Get the result from the Server DLL */ - Status = ServerDllInitProcedure(ServerDll); - - /* Check for Success */ - if (NT_SUCCESS(Status)) - { - /* - * Add this Server's Per-Process Data Size to the total that each - * process will need. - */ - CsrTotalPerProcessDataLength += ServerDll->SizeOfProcessData; - - /* Save the pointer in our list */ - CsrLoadedServerDll[ServerDll->ServerId] = ServerDll; - - /* Does it use our generic heap? */ - if (ServerDll->SharedSection != CsrSrvSharedSectionHeap) - { - /* No, save the pointer to its shared section in our list */ - CsrSrvSharedStaticServerData[ServerDll->ServerId] = ServerDll->SharedSection; - } - } - else - { - /* Use shared failure code */ - goto LoadFailed; - } - } - else - { -LoadFailed: - /* Server Init failed, unload it */ - if (hServerDll) LdrUnloadDll(hServerDll); - - /* Delete the Object */ - RtlFreeHeap(CsrHeap, 0, ServerDll); - } - - /* Return to caller */ - return Status; -} - -/*++ - * @name CsrServerDllInitialization - * @implemented NT4 - * - * The CsrServerDllInitialization is the initialization routine for - * the this Server DLL. - * - * @param LoadedServerDll - * Pointer to the CSR Server DLL structure representing this Server DLL. - * - * @return STATUS_SUCCESS. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll) -{ - /* Setup the DLL Object */ - LoadedServerDll->ApiBase = 0; - LoadedServerDll->HighestApiSupported = 5; - LoadedServerDll->DispatchTable = CsrServerApiDispatchTable; - LoadedServerDll->ValidTable = CsrServerApiServerValidTable; - LoadedServerDll->NameTable = CsrServerApiNameTable; - LoadedServerDll->SizeOfProcessData = 0; - LoadedServerDll->ConnectCallback = NULL; - LoadedServerDll->DisconnectCallback = NULL; - - /* All done */ - return STATUS_SUCCESS; -} - -/*++ - * @name CsrSrvClientConnect - * - * The CsrSrvClientConnect CSR API handles a new connection to a server DLL. - * - * @param ApiMessage - * Pointer to the CSR API Message for this request. - * - * @param Reply - * Optional reply to this request. - * - * @return STATUS_SUCCESS in case of success, STATUS_INVALID_PARAMETER - * or STATUS_TOO_MANY_NAMES in case of failure. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage, - IN OUT PULONG Reply OPTIONAL) -{ - 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; - *Reply = 0; - - /* Validate the ServerID */ - if (ClientConnect->ServerId >= CSR_SERVER_DLL_MAX) - { - return STATUS_TOO_MANY_NAMES; - } - else if (!CsrLoadedServerDll[ClientConnect->ServerId]) - { - return STATUS_INVALID_PARAMETER; - } - - /* Validate the Message Buffer */ - if (!(CsrValidateMessageBuffer(ApiMessage, - ClientConnect->ConnectionInfo, - ClientConnect->ConnectionInfoSize, - 1))) - { - /* Fail due to buffer overflow or other invalid buffer */ - return STATUS_INVALID_PARAMETER; - } - - /* Load the Server DLL */ - ServerDll = CsrLoadedServerDll[ClientConnect->ServerId]; - - /* Check if it has a Connect Callback */ - if (ServerDll->ConnectCallback) - { - /* Call the callback */ - Status = ServerDll->ConnectCallback(CurrentProcess, - ClientConnect->ConnectionInfo, - &ClientConnect->ConnectionInfoSize); - } - else - { - /* Assume success */ - Status = STATUS_SUCCESS; - } - - /* Return status */ - return Status; -} - -/*++ - * @name CsrSrvCreateSharedSection - * - * The CsrSrvCreateSharedSection creates the Shared Section that all CSR Server - * DLLs and Clients can use to share data. - * - * @param ParameterValue - * Specially formatted string from our registry command-line which - * specifies various arguments for the shared section. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrSrvCreateSharedSection(IN PCHAR ParameterValue) -{ - PCHAR SizeValue = ParameterValue; - ULONG Size; - NTSTATUS Status; - LARGE_INTEGER SectionSize; - 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++ = ANSI_NULL; - break; - } - else - { - SizeValue++; - } - } - - /* Make sure it's valid */ - if (!*SizeValue) return STATUS_INVALID_PARAMETER; - - /* Convert it to an integer */ - Status = RtlCharToInteger(SizeValue, 0, &Size); - if (!NT_SUCCESS(Status)) return Status; - - /* Multiply by 1024 entries and round to page size */ - CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize); - - /* Create the Secion */ - SectionSize.LowPart = CsrSrvSharedSectionSize; - SectionSize.HighPart = 0; - Status = NtCreateSection(&CsrSrvSharedSection, - SECTION_ALL_ACCESS, - NULL, - &SectionSize, - PAGE_EXECUTE_READWRITE, - SEC_BASED | SEC_RESERVE, - NULL); - if (!NT_SUCCESS(Status)) return Status; - - /* Map the section */ - Status = NtMapViewOfSection(CsrSrvSharedSection, - NtCurrentProcess(), - &CsrSrvSharedSectionBase, - 0, - 0, - NULL, - &ViewSize, - ViewUnmap, - MEM_TOP_DOWN, - PAGE_EXECUTE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - NtClose(CsrSrvSharedSection); - return Status; - } - - /* FIXME: Write the value to registry */ - - /* The Heap is the same place as the Base */ - CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase; - - /* Create the heap */ - if (!(RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_CLASS_7, - CsrSrvSharedSectionHeap, - CsrSrvSharedSectionSize, - PAGE_SIZE, - 0, - 0))) - { - /* Failure, unmap section and return */ - NtUnmapViewOfSection(NtCurrentProcess(), CsrSrvSharedSectionBase); - NtClose(CsrSrvSharedSection); - return STATUS_NO_MEMORY; - } - - /* Now allocate space from the heap for the Shared Data */ - CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap, - 0, - CSR_SERVER_DLL_MAX * - sizeof(PVOID)); - if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY; - - /* Write the values to the PEB */ - Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase; - Peb->ReadOnlySharedMemoryHeap = CsrSrvSharedSectionHeap; - Peb->ReadOnlyStaticServerData = CsrSrvSharedStaticServerData; - - /* Return */ - return STATUS_SUCCESS; -} - -/*++ - * @name CsrSrvAttachSharedSection - * - * The CsrSrvAttachSharedSection maps the CSR Shared Section into a new - * CSR Process' address space, and returns the pointers to the section - * through the Connection Info structure. - * - * @param CsrProcess - * Pointer to the CSR Process that is attempting a connection. - * - * @param ConnectInfo - * Pointer to the CSR Connection Info structure for the incoming - * connection. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL, - OUT PCSR_CONNECTION_INFO ConnectInfo) -{ - NTSTATUS Status; - ULONG ViewSize = 0; - - /* Check if we have a process */ - if (CsrProcess) - { - /* Map the sectio into this process */ - Status = NtMapViewOfSection(CsrSrvSharedSection, - CsrProcess->ProcessHandle, - &CsrSrvSharedSectionBase, - 0, - 0, - NULL, - &ViewSize, - ViewUnmap, - SEC_NO_CHANGE, - PAGE_EXECUTE_READ); - if (!NT_SUCCESS(Status)) return Status; - } - - /* Write the values in the Connection Info structure */ - ConnectInfo->SharedSectionBase = CsrSrvSharedSectionBase; - ConnectInfo->SharedSectionHeap = CsrSrvSharedSectionHeap; - ConnectInfo->SharedSectionData = CsrSrvSharedStaticServerData; - - /* Return success */ - return STATUS_SUCCESS; -} - -/*++ - * @name CsrSrvIdentifyAlertableThread - * @implemented NT4 - * - * The CsrSrvIdentifyAlertableThread CSR API marks a CSR Thread as alertable. - * - * @param ApiMessage - * Pointer to the CSR API Message for this request. - * - * @param Reply - * Pointer to an optional reply to this request. - * - * @return STATUS_SUCCESS. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrSrvIdentifyAlertableThread(IN OUT PCSR_API_MESSAGE ApiMessage, - IN OUT PULONG Reply) -{ - PCSR_THREAD CsrThread = NtCurrentTeb()->CsrClientThread; - - /* Set the alertable flag */ - CsrThread->Flags |= CsrThreadAltertable; - - /* Return success */ - return STATUS_SUCCESS; -} - -/*++ - * @name CsrSrvSetPriorityClass - * @implemented NT4 - * - * The CsrSrvSetPriorityClass CSR API is deprecated. - * - * @param ApiMessage - * Pointer to the CSR API Message for this request. - * - * @param Reply - * Pointer to an optional reply to this request. - * - * @return STATUS_SUCCESS. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrSrvSetPriorityClass(IN OUT PCSR_API_MESSAGE ApiMessage, - IN OUT PULONG Reply) -{ - /* Deprecated */ - return STATUS_SUCCESS; -} - -/*++ - * @name CsrSrvUnusedFunction - * @implemented NT4 - * - * The CsrSrvUnusedFunction CSR API is a stub for deprecated APIs. - * - * The CsrSrvSetPriorityClass CSR API is deprecated. - * - * @param ApiMessage - * Pointer to the CSR API Message for this request. - * - * @param Reply - * Pointer to an optional reply to this request. - * - * @return STATUS_INVALID_PARAMETER. - * - * @remarks CsrSrvSetPriorityClass does not use this stub because it must - * return success. - * - *--*/ -NTSTATUS -NTAPI -CsrSrvUnusedFunction(IN OUT PCSR_API_MESSAGE ApiMessage, - IN OUT PULONG Reply) -{ - /* Deprecated */ - return STATUS_INVALID_PARAMETER; -} - -/* PUBLIC FUNCTIONS***********************************************************/ - -/*++ - * @name CsrSetCallingSpooler - * @implemented NT4 - * - * the CsrSetCallingSpooler routine is deprecated. - * - * @param Reserved - * Deprecated - * - * @return None. - * - * @remarks This routine was used in archaic versions of NT for Printer Drivers. - * - *--*/ -VOID -NTAPI -CsrSetCallingSpooler(ULONG Reserved) -{ - /* Deprecated */ - return; -} - -/*++ - * @name CsrUnhandledExceptionFilter - * @implemented NT5 - * - * The CsrUnhandledExceptionFilter routine handles all exceptions - * within SEH-protected blocks. - * - * @param ExceptionPointers - * System-defined Argument. - * - * @return EXCEPTION_EXECUTE_HANDLER. - * - * @remarks None. - * - *--*/ -LONG -NTAPI -CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo) -{ - SYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo; - EXCEPTION_DISPOSITION Result = EXCEPTION_EXECUTE_HANDLER; - BOOLEAN OldValue; - NTSTATUS Status; - UNICODE_STRING ErrorSource; - ULONG_PTR ErrorParameters[4]; - ULONG Response; - - /* Check if a debugger is installed */ - Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, - &DebuggerInfo, - sizeof(DebuggerInfo), - NULL); - - /* Check if this is Session 0, and the Debugger is Enabled */ - if ((NtCurrentPeb()->SessionId) && (NT_SUCCESS(Status)) && - (DebuggerInfo.KernelDebuggerEnabled)) - { - /* Call the Unhandled Exception Filter */ - if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) != - EXCEPTION_CONTINUE_EXECUTION) - { - /* We're going to raise an error. Get Shutdown Privilege first */ - Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, - TRUE, - TRUE, - &OldValue); - - /* Use the Process token if that failed */ - if (Status == STATUS_NO_TOKEN) - { - Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, - TRUE, - FALSE, - &OldValue); - } - - /* Initialize our Name String */ - RtlInitUnicodeString(&ErrorSource, L"Windows SubSystem"); - - /* Set the parameters */ - ErrorParameters[0] = (ULONG_PTR)&ErrorSource; - ErrorParameters[1] = ExceptionInfo->ExceptionRecord->ExceptionCode; - ErrorParameters[2] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress; - ErrorParameters[3] = (ULONG_PTR)ExceptionInfo->ContextRecord; - - /* Bugcheck */ - Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, - 4, - 1, - ErrorParameters, - OptionShutdownSystem, - &Response); - } - - /* Just terminate us */ - NtTerminateProcess(NtCurrentProcess(), - ExceptionInfo->ExceptionRecord->ExceptionCode); - } - - return Result; -} - -/* EOF */ diff --git a/subsystems/csr/csrsrv/session.c b/subsystems/csr/csrsrv/session.c deleted file mode 100644 index 2ec08a66a4f..00000000000 --- a/subsystems/csr/csrsrv/session.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System - * FILE: subsys/csr/csrsrv/session.c - * PURPOSE: CSR Server DLL Session Implementation - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES ******************************************************************/ - -#include "srv.h" - -#define NDEBUG -#include - -/* DATA **********************************************************************/ - -RTL_CRITICAL_SECTION CsrNtSessionLock; -LIST_ENTRY CsrNtSessionList; -HANDLE CsrSmApiPort; - -PSB_API_ROUTINE CsrServerSbApiDispatch[5] = -{ - CsrSbCreateSession, - CsrSbTerminateSession, - CsrSbForeignSessionComplete, - CsrSbCreateProcess, - NULL -}; - -PCHAR CsrServerSbApiName[5] = -{ - "SbCreateSession", - "SbTerminateSession", - "SbForeignSessionComplete", - "SbCreateProcess", - "Unknown Csr Sb Api Number" -}; - -/* PRIVATE FUNCTIONS *********************************************************/ - -/*++ - * @name CsrInitializeNtSessionList - * - * The CsrInitializeNtSessionList routine sets up support for CSR Sessions. - * - * @param None - * - * @return None - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrInitializeNtSessionList(VOID) -{ - DPRINT("CSRSRV: %s called\n", __FUNCTION__); - - /* Initialize the Session List */ - InitializeListHead(&CsrNtSessionList); - - /* Initialize the Session Lock */ - return RtlInitializeCriticalSection(&CsrNtSessionLock); -} - -/*++ - * @name CsrAllocateNtSession - * - * The CsrAllocateNtSession routine allocates a new CSR NT Session. - * - * @param SessionId - * Session ID of the CSR NT Session to allocate. - * - * @return Pointer to the newly allocated CSR NT Session. - * - * @remarks None. - * - *--*/ -PCSR_NT_SESSION -NTAPI -CsrAllocateNtSession(IN ULONG SessionId) -{ - PCSR_NT_SESSION NtSession; - - /* Allocate an NT 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->SessionLink); - CsrReleaseNtSessionLock(); - } - else - { - ASSERT(NtSession != NULL); - } - - /* Return the Session (or NULL) */ - return NtSession; -} - -/*++ - * @name CsrReferenceNtSession - * - * The CsrReferenceNtSession increases the reference count of a CSR NT Session. - * - * @param Session - * Pointer to the CSR NT Session to reference. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -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++; - - /* Release the lock */ - CsrReleaseNtSessionLock(); -} - -/*++ - * @name CsrDereferenceNtSession - * - * The CsrDereferenceNtSession decreases the reference count of a - * CSR NT Session. - * - * @param Session - * 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. - * - * @return None. - * - * @remarks CsrDereferenceNtSession will complete the session if - * the last reference to it has been closed. - * - *--*/ -VOID -NTAPI -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->SessionLink); - - /* Release the lock */ - CsrReleaseNtSessionLock(); - - /* Tell SM that we're done here */ - SmSessionComplete(CsrSmApiPort, Session->SessionId, ExitStatus); - - /* Free the Session Object */ - RtlFreeHeap(CsrHeap, 0, Session); - } - else - { - /* Release the lock, the Session is still active */ - CsrReleaseNtSessionLock(); - } -} - - -/* SESSION MANAGER FUNCTIONS**************************************************/ - -/*++ - * @name CsrSbCreateSession - * - * The CsrSbCreateSession API is called by the Session Manager whenever a new - * session is created. - * - * @param ApiMessage - * Pointer to the Session Manager API Message. - * - * @return TRUE in case of success, FALSE othwerwise. - * - * @remarks The CsrSbCreateSession routine will initialize a new CSR NT - * Session and allocate a new CSR Process for the subsystem process. - * - *--*/ -BOOLEAN -NTAPI -CsrSbCreateSession(IN PSB_API_MSG ApiMessage) -{ - PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession; - HANDLE hProcess, hThread; - PCSR_PROCESS CsrProcess; - NTSTATUS Status; - KERNEL_USER_TIMES KernelTimes; - PCSR_THREAD CsrThread; - PVOID ProcessData; - ULONG i; - - /* Save the Process and Thread Handles */ - hProcess = CreateSession->ProcessInfo.ProcessHandle; - hThread = CreateSession->ProcessInfo.ThreadHandle; - - /* Lock the Processes */ - CsrAcquireProcessLock(); - - /* Allocate a new process */ - CsrProcess = CsrAllocateProcess(); - if (!CsrProcess) - { - /* Fail */ - ApiMessage->ReturnValue = STATUS_NO_MEMORY; - CsrReleaseProcessLock(); - return TRUE; - } - - /* Set the exception port */ - Status = NtSetInformationProcess(hProcess, - ProcessExceptionPort, - &CsrApiPort, - sizeof(HANDLE)); - - /* Check for success */ - if (!NT_SUCCESS(Status)) - { - /* Fail the request */ - CsrDeallocateProcess(CsrProcess); - CsrReleaseProcessLock(); - - /* Strange as it seems, NTSTATUSes are actually returned */ - return (BOOLEAN)STATUS_NO_MEMORY; - } - - /* Get the Create Time */ - Status = NtQueryInformationThread(hThread, - ThreadTimes, - &KernelTimes, - sizeof(KERNEL_USER_TIMES), - NULL); - - /* Check for success */ - if (!NT_SUCCESS(Status)) - { - /* Fail the request */ - CsrDeallocateProcess(CsrProcess); - CsrReleaseProcessLock(); - - /* Strange as it seems, NTSTATUSes are actually returned */ - return (BOOLEAN)Status; - } - - /* Allocate a new Thread */ - CsrThread = CsrAllocateThread(CsrProcess); - if (!CsrThread) - { - /* Fail the request */ - CsrDeallocateProcess(CsrProcess); - ApiMessage->ReturnValue = STATUS_NO_MEMORY; - CsrReleaseProcessLock(); - return TRUE; - } - - /* Setup the Thread Object */ - 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); - - /* Setup Process Data */ - CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId; - CsrProcess->ProcessHandle = hProcess; - CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId); - - /* Set the Process Priority */ - CsrSetBackgroundPriority(CsrProcess); - - /* Get the first data location */ - ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX]; - - /* Loop every DLL */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Check if the DLL is loaded and has Process Data */ - if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData) - { - /* Write the pointer to the data */ - CsrProcess->ServerData[i] = ProcessData; - - /* Move to the next data location */ - ProcessData = (PVOID)((ULONG_PTR)ProcessData + - CsrLoadedServerDll[i]->SizeOfProcessData); - } - else - { - /* Nothing for this Process */ - CsrProcess->ServerData[i] = NULL; - } - } - - /* Insert the Process */ - CsrInsertProcess(NULL, NULL, CsrProcess); - - /* Activate the Thread */ - ApiMessage->ReturnValue = NtResumeThread(hThread, NULL); - - /* Release lock and return */ - CsrReleaseProcessLock(); - return TRUE; -} - -/*++ - * @name CsrSbForeignSessionComplete - * - * The CsrSbForeignSessionComplete API is called by the Session Manager - * whenever a foreign session is completed (ie: terminated). - * - * @param ApiMessage - * Pointer to the Session Manager API Message. - * - * @return TRUE in case of success, FALSE othwerwise. - * - * @remarks The CsrSbForeignSessionComplete API is not yet implemented. - * - *--*/ -BOOLEAN -NTAPI -CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage) -{ - /* Deprecated/Unimplemented in NT */ - 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/subsystems/csr/csrsrv/srv.h b/subsystems/csr/csrsrv/srv.h deleted file mode 100644 index 48a9f0f1345..00000000000 --- a/subsystems/csr/csrsrv/srv.h +++ /dev/null @@ -1,395 +0,0 @@ -#ifndef _SRV_H -#define _SRV_H - -/* PSDK/NDK Headers */ -#define NTOS_MODE_USER -#include -#define WIN32_NO_STATUS -#include -#include -#include - -/* CSR Header */ -#include -#include - -/* PSEH for SEH Support */ -#include - -/* DEFINES *******************************************************************/ - -#define CSR_SERVER_DLL_MAX 4 - -#define CsrAcquireProcessLock() \ - RtlEnterCriticalSection(&CsrProcessLock); - -#define CsrReleaseProcessLock() \ - RtlLeaveCriticalSection(&CsrProcessLock); - -#define CsrAcquireWaitLock() \ - RtlEnterCriticalSection(&CsrWaitListsLock); - -#define CsrReleaseWaitLock() \ - RtlLeaveCriticalSection(&CsrWaitListsLock); - -#define CsrAcquireNtSessionLock() \ - RtlEnterCriticalSection(&CsrNtSessionLock) - -#define CsrReleaseNtSessionLock() \ - RtlLeaveCriticalSection(&CsrNtSessionLock) - -#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" - -#define SESSION_ROOT L"\\Sessions" -#define GLOBAL_ROOT L"\\GLOBAL??" -#define SYMLINK_NAME L"SymbolicLink" -#define SB_PORT_NAME L"SbAbiPort" -#define CSR_PORT_NAME L"ApiPort" -#define UNICODE_PATH_SEP L"\\" - -#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align)) -#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l)) - -/* DATA **********************************************************************/ - -extern ULONG CsrTotalPerProcessDataLength; -extern ULONG CsrMaxApiRequestThreads; -extern PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]; -extern PCSR_PROCESS CsrRootProcess; -extern UNICODE_STRING CsrSbApiPortName; -extern UNICODE_STRING CsrApiPortName; -extern HANDLE CsrSbApiPort; -extern HANDLE CsrSmApiPort; -extern HANDLE CsrApiPort; -extern HANDLE CsrHeap; -extern RTL_CRITICAL_SECTION CsrProcessLock; -extern RTL_CRITICAL_SECTION CsrWaitListsLock; -extern LIST_ENTRY CsrThreadHashTable[256]; -extern HANDLE CsrInitializationEvent; -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( - IN PCHAR DllString, - IN PCHAR EntryPoint, - IN ULONG ServerId -); - -NTSTATUS -NTAPI -CsrServerInitialization( - ULONG ArgumentCount, - 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); - -NTSTATUS -NTAPI -CsrCreateObjectDirectory(IN PCHAR ObjectDirectory); - -NTSTATUS -NTAPI -CsrSrvCreateSharedSection(IN PCHAR ParameterValue); - -NTSTATUS -NTAPI -CsrInitializeNtSessionList(VOID); - -NTSTATUS -NTAPI -CsrInitializeProcessStructure(VOID); - -NTSTATUS -NTAPI -CsrApiPortInitialize(VOID); - -NTSTATUS -NTAPI -CsrSbApiPortInitialize(VOID); - -BOOLEAN -NTAPI -CsrSbCreateSession(IN PSB_API_MSG ApiMessage); - -BOOLEAN -NTAPI -CsrSbTerminateSession(IN PSB_API_MSG ApiMessage); - -BOOLEAN -NTAPI -CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage); - -BOOLEAN -NTAPI -CsrSbCreateProcess(IN PSB_API_MSG ApiMessage); - -PCSR_PROCESS -NTAPI -CsrAllocateProcess(VOID); - -PCSR_THREAD -NTAPI -CsrAllocateThread(IN PCSR_PROCESS CsrProcess); - -VOID -NTAPI -CsrInsertThread( - IN PCSR_PROCESS Process, - IN PCSR_THREAD Thread -); - -VOID -NTAPI -CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess); - -VOID -NTAPI -CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess); - -NTSTATUS -NTAPI -CsrGetProcessLuid( - HANDLE hProcess, - PLUID Luid -); - -BOOLEAN -NTAPI -CsrImpersonateClient(IN PCSR_THREAD CsrThread); - -BOOLEAN -NTAPI -CsrRevertToSelf(VOID); - -PCSR_THREAD -NTAPI -CsrLocateThreadByClientId( - OUT PCSR_PROCESS *Process, - IN PCLIENT_ID ClientId -); - -VOID -NTAPI -CsrDereferenceNtSession( - IN PCSR_NT_SESSION Session, - NTSTATUS ExitStatus -); - -VOID -NTAPI -CsrReferenceNtSession(PCSR_NT_SESSION Session); - -VOID -NTAPI -CsrLockedDereferenceThread(PCSR_THREAD CsrThread); - -VOID -NTAPI -CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess); - -NTSTATUS -NTAPI -CsrLockProcessByClientId( - IN HANDLE Pid, - OUT PCSR_PROCESS *CsrProcess OPTIONAL -); - -NTSTATUS -NTAPI -CsrUnlockProcess(PCSR_PROCESS CsrProcess); - -NTSTATUS -NTAPI -CsrSrvClientConnect( - IN OUT PCSR_API_MESSAGE ApiMessage, - IN OUT PULONG Reply -); - -NTSTATUS -NTAPI -CsrSrvUnusedFunction( - IN OUT PCSR_API_MESSAGE ApiMessage, - IN OUT PULONG Reply -); - -NTSTATUS -NTAPI -CsrSrvIdentifyAlertableThread( - IN OUT PCSR_API_MESSAGE ApiMessage, - IN OUT PULONG Reply -); - -NTSTATUS -NTAPI -CsrSrvSetPriorityClass( - IN OUT PCSR_API_MESSAGE ApiMessage, - IN OUT PULONG Reply -); - -NTSTATUS -NTAPI -CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll); - -VOID -NTAPI -CsrDereferenceThread(PCSR_THREAD CsrThread); - -VOID -NTAPI -CsrSbApiRequestThread(IN PVOID Parameter); - -NTSTATUS -NTAPI -CsrApiRequestThread(IN PVOID Parameter); - -BOOLEAN -NTAPI -ProtectHandle(IN HANDLE ObjectHandle); - -PCSR_THREAD -NTAPI -CsrAddStaticServerThread( - IN HANDLE hThread, - IN PCLIENT_ID ClientId, - IN ULONG ThreadFlags -); - -PCSR_THREAD -NTAPI -CsrConnectToUser(VOID); - -PCSR_THREAD -NTAPI -CsrLocateThreadInProcess( - IN PCSR_PROCESS CsrProcess OPTIONAL, - IN PCLIENT_ID Cid -); - -NTSTATUS -NTAPI -CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message); - -NTSTATUS -NTAPI -CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage); - -NTSTATUS -NTAPI -CsrSrvAttachSharedSection( - IN PCSR_PROCESS CsrProcess OPTIONAL, - OUT PCSR_CONNECTION_INFO ConnectInfo -); - -VOID -NTAPI -CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage); - -BOOLEAN -NTAPI -CsrNotifyWaitBlock( - IN PCSR_WAIT_BLOCK WaitBlock, - IN PLIST_ENTRY WaitList, - IN PVOID WaitArgument1, - IN PVOID WaitArgument2, - IN ULONG WaitFlags, - IN BOOLEAN DereferenceThread -); - -VOID -NTAPI -CsrDereferenceProcess(PCSR_PROCESS CsrProcess); - -VOID -NTAPI -CsrInsertProcess( - IN PCSR_PROCESS Parent OPTIONAL, - IN PCSR_PROCESS CurrentProcess OPTIONAL, - IN PCSR_PROCESS CsrProcess -); - -NTSTATUS -NTAPI -CsrPopulateDosDevicesDirectory( - IN HANDLE DosDevicesDirectory, - IN PPROCESS_DEVICEMAP_INFORMATION DeviceMap -); - -BOOLEAN -NTAPI -CsrValidateMessageBuffer( - IN PCSR_API_MESSAGE ApiMessage, - IN PVOID *Buffer, - IN ULONG ArgumentSize, - IN ULONG ArgumentCount -); - -NTSTATUS -NTAPI -CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd); - -NTSTATUS -NTAPI -CsrDestroyThread(IN PCLIENT_ID Cid); - -NTSTATUS -NTAPI -CsrDestroyProcess( - IN PCLIENT_ID Cid, - IN NTSTATUS ExitStatus -); - -LONG -NTAPI -CsrUnhandledExceptionFilter( - IN PEXCEPTION_POINTERS ExceptionInfo -); - -VOID -NTAPI -CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess); - -VOID -NTAPI -CsrThreadRefcountZero(IN PCSR_THREAD CsrThread); - -NTSTATUS -NTAPI -CsrSetDirectorySecurity(IN HANDLE ObjectDirectory); -#endif diff --git a/subsystems/csr/csrsrv/status.h b/subsystems/csr/csrsrv/status.h deleted file mode 100644 index e619443abd3..00000000000 --- a/subsystems/csr/csrsrv/status.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * CSRSRV Status - */ - -/* Organization - * - * api.c - Handles the LPC Reply/Request Threads which wait on Sb and Csr APIs. - * Also in charge of creating those threads and setting up the ports. - * Finally, it provides external APIs for validating the API buffers - * and doing server-to-server API calls. - * - * init.c - Handles initialization of CSRSRV, including command-line parsing, - * loading the Server DLLs, creating the Session Directories, setting - * up the DosDevices Object Directory, and initializing each component. - * - * process.c - Handles all internal functions dealing with the CSR Process Object, - * including de/allocation, de/referencing, un/locking, prority, and - * lookups. Also handles all external APIs which touch the CSR Process Object. - * - * server.c - Handles all internal functions related to loading and managing Server - * DLLs, as well as the routines handling the Shared Static Memory Section. - * Holds the API Dispatch/Valid/Name Tables and the public CSR_SERVER API - * interface. Also home of the SEH handler. - * - * session.c - Handles all internal functions dealing with the CSR Session Object, - * including de/allocation, de/referencing, and un/locking. Holds the SB API - * Dispatch/Name Tables and the public CsrSv API Interface for commmunication - * with the Session Manager. - * - * thread.c - Handles all internal functions dealing with the CSR Thread Object, - * including de/allocation, de/referencing, un/locking, impersonation, and - * lookups. Also handles all external APIs which touch the CSR Thread Object. - * - * wait.c - Handles all internal functions dealing with the CSR Wait Object, - * including de/allocation, de/referencing and un/locking. Also implements - * the external Wait API for creating, removing and/or notifying waits. - */ - -/* Exported APIs, their location, and their status - * CsrAddStaticServerThread 753E679E 1 - server.c - IMPLEMENTED - * CsrCallServerFromServer 753E4FD9 2 - api.c - IMPLEMENTED - * CsrConnectToUser 753E4E48 3 - api.c - IMPLEMENTED - * CsrCreateProcess 753E6FD3 4 - process.c - IMPLEMENTED - * CsrCreateRemoteThread 753E73BD 5 - thread.c - IMPLEMENTED - * CsrCreateThread 753E72DA 6 - thread.c - IMPLEMENTED - * CsrCreateWait 753E770E 7 - wait.c - IMPLEMENTED - * CsrDebugProcess 753E7682 8 - process.c - IMPLEMENTED - * CsrDebugProcessStop 753E768A 9 - process.c - IMPLEMENTED - * CsrDereferenceProcess 753E6281 10 - process.c - IMPLEMENTED - * CsrDereferenceThread 753E6964 11 - thread.c - IMPLEMENTED - * CsrDereferenceWait 753E7886 12 - wait.c - IMPLEMENTED - * CsrDestroyProcess 753E7225 13 - process.c - IMPLEMENTED - * CsrDestroyThread 753E7478 14 - thread.c - IMPLEMENTED - * CsrExecServerThread 753E6841 15 - thread.c - IMPLEMENTED - * CsrGetProcessLuid 753E632F 16 - process.c - IMPLEMENTED - * CsrImpersonateClient 753E60F8 17 - thread.c - IMPLEMENTED - * CsrLockProcessByClientId 753E668F 18 - process.c - IMPLEMENTED - * CsrLockThreadByClientId 753E6719 19 - thread.c - IMPLEMENTED - * CsrMoveSatisfiedWait 753E7909 20 - wait.c - IMPLEMENTED - * CsrNotifyWait 753E782F 21 - wait.c - IMPLEMENTED - * CsrPopulateDosDevices 753E37A5 22 - init.c - IMPLEMENTED - * CsrQueryApiPort 753E4E42 23 - api.c - IMPLEMENTED - * CsrReferenceThread 753E61E5 24 - thread.c - IMPLEMENTED - * CsrRevertToSelf 753E615A 25 - thread.c - IMPLEMENTED - * CsrServerInitialization 753E3D75 26 - server.c - IMPLEMENTED - * CsrSetBackgroundPriority 753E5E87 27 - process.c - IMPLEMENTED - * CsrSetCallingSpooler 753E6425 28 - server.c - IMPLEMENTED - * CsrSetForegroundPriority 753E5E67 29 - process.c - IMPLEMENTED - * CsrShutdownProcesses 753E7547 30 - process.c - IMPLEMENTED - * CsrUnhandledExceptionFilter 753E3FE3 31 - server.c - IMPLEMENTED - * CsrUnlockProcess 753E66FD 32 - process.c - IMPLEMENTED - * CsrUnlockThread 753E7503 33 - thread.c - IMPLEMENTED - * CsrValidateMessageBuffer 753E528D 34 - api.c - IMPLEMENTED - * CsrValidateMessageString 753E5323 35 - api.c - UNIMPLEMENTED - */ - -/* Public CSR API Interface Status (server.c) - * CsrSrvClientConnect - IMPLEMENTED - * CsrSrvUnusedFunction - IMPLEMENTED - * CsrSrvIdentifyAlertableThread - IMPLEMENTED - * CsrSrvSetPriorityClass - IMPLEMENTED - */ - -/* Public SB API Interface Status (session.c) - * CsrSbCreateSession - IMPLEMENTED - * CsrSbForeignSessionComplete - IMPLEMENTED - * CsrSbTerminateSession - UNIMPLEMENTED - * CsrSbCreateProcess - UNIMPLEMENTED - */ - -/* What's missing: - * - * - 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. [DONE!] - * - * - NTDLL needs to get the Csr* routines properly implemented. [DONE!] - * - * - KERNEL32, USER32 need to register with their servers properly. - * Additionally, user32 needs to have ClientThreadStartup implemented - * properly and do the syscall NtUserInitialize (I think) which also - * needs to be implemented in win32k.sys. All this should be less then - * 100 lines of code. [KERNEL32 50% DONE, USER32 NOT DONE] - * - * - The skeleton code for winsrv and basesrv which connects with CSR/CSRSRV - * needs to be written. [NOT DONE] - * - * - The kernel's LPC implementation needs to be made compatible. [DONE!] - */ - diff --git a/subsystems/csr/csrsrv/thread.c b/subsystems/csr/csrsrv/thread.c deleted file mode 100644 index c03f61d82b0..00000000000 --- a/subsystems/csr/csrsrv/thread.c +++ /dev/null @@ -1,1056 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System - * FILE: subsys/csr/csrsrv/thread.c - * PURPOSE: CSR Server DLL Thread Implementation - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES ******************************************************************/ - -#include "srv.h" - -#define NDEBUG -#include - -/* DATA **********************************************************************/ - -LIST_ENTRY CsrThreadHashTable[256]; -SECURITY_QUALITY_OF_SERVICE CsrSecurityQos = -{ - sizeof(SECURITY_QUALITY_OF_SERVICE), - SecurityImpersonation, - SECURITY_STATIC_TRACKING, - FALSE -}; - -/* PRIVATE FUNCTIONS *********************************************************/ - -/*++ - * @name CsrAllocateThread - * - * The CsrAllocateThread routine allocates a new CSR Thread object. - * - * @param CsrProcess - * Pointer to the CSR Process which will contain this CSR Thread. - * - * @return Pointer to the newly allocated CSR Thread. - * - * @remarks None. - * - *--*/ -PCSR_THREAD -NTAPI -CsrAllocateThread(IN PCSR_PROCESS CsrProcess) -{ - PCSR_THREAD CsrThread; - - /* Allocate the structure */ - CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD)); - if (!CsrThread) return NULL; - - /* Reference the Thread and Process */ - CsrThread->ReferenceCount++; - CsrProcess->ReferenceCount++; - - /* Set the Parent Process */ - CsrThread->Process = CsrProcess; - - /* Return Thread */ - return CsrThread; -} - -/*++ - * @name CsrLocateThreadByClientId - * - * The CsrLocateThreadByClientId routine locates the CSR Thread and, - * optionally, its parent CSR Process, corresponding to a Client ID. - * - * @param Process - * Optional pointer to a CSR Process pointer which will contain - * the CSR Thread's parent. - * - * @param ClientId - * Pointer to a Client ID structure containing the Unique Thread ID - * to look up. - * - * @return Pointer to the CSR Thread corresponding to this CID, or NULL if - * none was found. - * - * @remarks None. - * - *--*/ -PCSR_THREAD -NTAPI -CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, - IN PCLIENT_ID ClientId) -{ - ULONG i; - PLIST_ENTRY NextEntry; - PCSR_THREAD FoundThread; - ASSERT(ProcessStructureListLocked()); - - /* Hash the Thread */ - i = CsrHashThread(ClientId->UniqueThread); - - /* Set the list pointers */ - NextEntry = CsrThreadHashTable[i].Flink; - - /* Star the loop */ - while (NextEntry != &CsrThreadHashTable[i]) - { - /* Get the thread */ - FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); - - /* Compare the CID */ - if (*(PULONGLONG)&FoundThread->ClientId == *(PULONGLONG)ClientId) - { - /* Match found, return the process */ - *Process = FoundThread->Process; - - /* Return thread too */ - return FoundThread; - } - - /* Next */ - NextEntry = NextEntry->Flink; - } - - /* Nothing found */ - return NULL; -} - -/*++ - * @name CsrLocateThreadInProcess - * - * The CsrLocateThreadInProcess routine locates the CSR Thread - * corresponding to a Client ID inside a specific CSR Process. - * - * @param Process - * Optional pointer to the CSR Process which contains the CSR Thread - * that will be looked up. - * - * @param ClientId - * Pointer to a Client ID structure containing the Unique Thread ID - * to look up. - * - * @return Pointer to the CSR Thread corresponding to this CID, or NULL if - * none was found. - * - * @remarks If the CsrProcess argument is NULL, the lookup will be done inside - * CsrRootProcess. - * - *--*/ -PCSR_THREAD -NTAPI -CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, - IN PCLIENT_ID Cid) -{ - PLIST_ENTRY NextEntry; - PCSR_THREAD FoundThread = NULL; - - /* Use the Root Process if none was specified */ - if (!CsrProcess) CsrProcess = CsrRootProcess; - - /* Save the List pointers */ - NextEntry = CsrProcess->ThreadList.Flink; - - /* Start the Loop */ - while (NextEntry != &CsrProcess->ThreadList) - { - /* Get Thread Entry */ - FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link); - - /* Check for TID Match */ - if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break; - - /* Next entry */ - NextEntry = NextEntry->Flink; - } - - /* Return what we found */ - return FoundThread; -} - -/*++ - * @name CsrInsertThread - * - * The CsrInsertThread routine inserts a CSR Thread into its parent's - * Thread List and into the Thread Hash Table. - * - * @param Process - * Pointer to the CSR Process containing this CSR Thread. - * - * @param Thread - * Pointer to the CSR Thread to be inserted. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrInsertThread(IN PCSR_PROCESS Process, - IN PCSR_THREAD Thread) -{ - ULONG i; - ASSERT(ProcessStructureListLocked()); - - /* Insert it into the Regular List */ - InsertTailList(&Process->ThreadList, &Thread->Link); - - /* Increase Thread Count */ - Process->ThreadCount++; - - /* Hash the Thread */ - i = CsrHashThread(Thread->ClientId.UniqueThread); - - /* Insert it there too */ - InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks); -} - -/*++ - * @name CsrDeallocateThread - * - * The CsrDeallocateThread frees the memory associated with a CSR Thread. - * - * @param CsrThread - * Pointer to the CSR Thread to be freed. - * - * @return None. - * - * @remarks Do not call this routine. It is reserved for the internal - * thread management routines when a CSR Thread has been cleanly - * dereferenced and killed. - * - *--*/ -VOID -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 - * - * The CsrLockedDereferenceThread derefences a CSR Thread while the - * Process Lock is already being held. - * - * @param CsrThread - * Pointer to the CSR Thread to be dereferenced. - * - * @return None. - * - * @remarks This routine will return with the Process Lock held. - * - *--*/ -VOID -NTAPI -CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread) -{ - LONG LockCount; - - /* Decrease reference count */ - LockCount = --CsrThread->ReferenceCount; - ASSERT(LockCount >= 0); - if (!LockCount) - { - /* Call the generic cleanup code */ - CsrThreadRefcountZero(CsrThread); - CsrAcquireProcessLock(); - } -} - -/*++ - * @name CsrRemoveThread - * - * The CsrRemoveThread function undoes a CsrInsertThread operation and - * removes the CSR Thread from the the Hash Table and Thread List. - * - * @param CsrThread - * Pointer to the CSR Thread to remove. - * - * @return None. - * - * @remarks If this CSR Thread is the last one inside a CSR Process, the - * parent will be dereferenced and the CsrProcessLastThreadTerminated - * flag will be set. - * - * After executing this routine, the CSR Thread will have the - * CsrThreadInTermination flag set. - * - *--*/ -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; - - /* Remove it from the Hash List as well */ - if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks); - - /* Check if this is the last Thread */ - if (!CsrThread->Process->ThreadCount) - { - /* Check if it's not already been marked for deletion */ - if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated)) - { - /* Let everyone know this process is about to lose the thread */ - CsrThread->Process->Flags |= CsrProcessLastThreadTerminated; - - /* Reference the Process */ - CsrLockedDereferenceProcess(CsrThread->Process); - } - } - - /* Mark the thread for deletion */ - CsrThread->Flags |= CsrThreadInTermination; -} - -/*++ - * @name CsrThreadRefcountZero - * - * The CsrThreadRefcountZero routine is executed when a CSR Thread has lost - * all its active references. It removes and de-allocates the CSR Thread. - * - * @param CsrThread - * Pointer to the CSR Thread that is to be deleted. - * - * @return None. - * - * @remarks Do not call this routine. It is reserved for the internal - * thread management routines when a CSR Thread has lost all - * its references. - * - * This routine is called with the Process Lock held. - * - *--*/ -VOID -NTAPI -CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) -{ - PCSR_PROCESS CsrProcess = CsrThread->Process; - NTSTATUS Status; - - /* Remove this thread */ - CsrRemoveThread(CsrThread); - - /* Release the Process Lock */ - CsrReleaseProcessLock(); - - /* Close the NT Thread Handle */ - UnProtectHandle(CsrThread->ThreadHandle); - Status = NtClose(CsrThread->ThreadHandle); - ASSERT(NT_SUCCESS(Status)); - - /* De-allocate the CSR Thread Object */ - CsrDeallocateThread(CsrThread); - - /* Remove a reference from the process */ - CsrDereferenceProcess(CsrProcess); -} - -/* PUBLIC FUNCTIONS ***********************************************************/ - -/*++ - * @name CsrAddStaticServerThread - * @implemented NT4 - * - * The CsrAddStaticServerThread routine adds a new CSR Thread to the - * CSR Server Process (CsrRootProcess). - * - * @param hThread - * Handle to an existing NT Thread to which to associate this - * CSR Thread. - * - * @param ClientId - * Pointer to the Client ID structure of the NT Thread to associate - * with this CSR Thread. - * - * @param ThreadFlags - * Initial CSR Thread Flags to associate to this CSR Thread. Usually - * CsrThreadIsServerThread. - * - * @return Pointer to the newly allocated CSR Thread. - * - * @remarks None. - * - *--*/ -PCSR_THREAD -NTAPI -CsrAddStaticServerThread(IN HANDLE hThread, - IN PCLIENT_ID ClientId, - IN ULONG ThreadFlags) -{ - PCSR_THREAD CsrThread; - - /* Get the Lock */ - CsrAcquireProcessLock(); - - /* Allocate the Server Thread */ - CsrThread = CsrAllocateThread(CsrRootProcess); - if (CsrThread) - { - /* Setup the Object */ - CsrThread->ThreadHandle = hThread; - ProtectHandle(hThread); - CsrThread->ClientId = *ClientId; - CsrThread->Flags = ThreadFlags; - - /* Insert it into the Thread List */ - InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link); - - /* Increment the thread count */ - CsrRootProcess->ThreadCount++; - } - else - { - DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread); - } - - /* Release the Process Lock and return */ - CsrReleaseProcessLock(); - return CsrThread; -} - -/*++ - * @name CsrCreateRemoteThread - * @implemented NT4 - * - * The CsrCreateRemoteThread routine creates a CSR Thread object for - * an NT Thread which is not part of the current NT Process. - * - * @param hThread - * Handle to an existing NT Thread to which to associate this - * CSR Thread. - * - * @param ClientId - * Pointer to the Client ID structure of the NT Thread to associate - * with this CSR Thread. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrCreateRemoteThread(IN HANDLE hThread, - IN PCLIENT_ID ClientId) -{ - NTSTATUS Status; - HANDLE ThreadHandle; - PCSR_THREAD CsrThread; - PCSR_PROCESS CsrProcess; - KERNEL_USER_TIMES KernelTimes; - - DPRINT("CSRSRV: %s called\n", __FUNCTION__); - - /* Get the Thread Create Time */ - Status = NtQueryInformationThread(hThread, - ThreadTimes, - &KernelTimes, - sizeof(KernelTimes), - NULL); - if (!NT_SUCCESS(Status)) return Status; - - /* Lock the Owner Process */ - Status = CsrLockProcessByClientId(&ClientId->UniqueProcess, &CsrProcess); - - /* Make sure the thread didn't terminate */ - if (KernelTimes.ExitTime.QuadPart) - { - /* Unlock the process and return */ - CsrUnlockProcess(CsrProcess); - return STATUS_THREAD_IS_TERMINATING; - } - - /* Allocate a CSR Thread Structure */ - CsrThread = CsrAllocateThread(CsrProcess); - if (!CsrThread) - { - DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__); - CsrUnlockProcess(CsrProcess); - return STATUS_NO_MEMORY; - } - - /* Duplicate the Thread Handle */ - Status = NtDuplicateObject(NtCurrentProcess(), - hThread, - NtCurrentProcess(), - &ThreadHandle, - 0, - 0, - DUPLICATE_SAME_ACCESS); - /* Allow failure */ - if (!NT_SUCCESS(Status)) ThreadHandle = hThread; - - /* Save the data we have */ - CsrThread->CreateTime = KernelTimes.CreateTime; - CsrThread->ClientId = *ClientId; - CsrThread->ThreadHandle = ThreadHandle; - ProtectHandle(ThreadHandle); - CsrThread->Flags = 0; - - /* Insert the Thread into the Process */ - CsrInsertThread(CsrProcess, CsrThread); - - /* Release the lock and return */ - CsrUnlockProcess(CsrProcess); - return STATUS_SUCCESS; -} - -/*++ - * @name CsrCreateThread - * @implemented NT4 - * - * The CsrCreateThread routine creates a CSR Thread object for an NT Thread. - * - * @param CsrProcess - * Pointer to the CSR Process which will contain the CSR Thread. - * - * @param hThread - * Handle to an existing NT Thread to which to associate this - * CSR Thread. - * - * @param ClientId - * Pointer to the Client ID structure of the NT Thread to associate - * with this CSR Thread. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrCreateThread(IN PCSR_PROCESS CsrProcess, - IN HANDLE hThread, - IN PCLIENT_ID ClientId, - IN BOOLEAN HaveClient) -{ - NTSTATUS Status; - PCSR_THREAD CsrThread, CurrentThread; - PCSR_PROCESS CurrentProcess; - CLIENT_ID CurrentCid; - KERNEL_USER_TIMES KernelTimes; - DPRINT("CSRSRV: %s called\n", __FUNCTION__); - - if (HaveClient) - { - /* 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 */ - Status = NtQueryInformationThread(hThread, - ThreadTimes, - (PVOID)&KernelTimes, - sizeof(KernelTimes), - NULL); - if (!NT_SUCCESS(Status)) - { - CsrReleaseProcessLock(); - return Status; - } - - /* Allocate a CSR Thread Structure */ - CsrThread = CsrAllocateThread(CsrProcess); - if (!CsrThread) - { - DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__); - CsrReleaseProcessLock(); - return STATUS_NO_MEMORY; - } - - /* Save the data we have */ - CsrThread->CreateTime = KernelTimes.CreateTime; - CsrThread->ClientId = *ClientId; - CsrThread->ThreadHandle = hThread; - ProtectHandle(hThread); - CsrThread->Flags = 0; - - /* Insert the Thread into the Process */ - CsrInsertThread(CsrProcess, CsrThread); - - /* Release the lock and return */ - CsrReleaseProcessLock(); - return STATUS_SUCCESS; -} - -/*++ - * @name CsrDereferenceThread - * @implemented NT4 - * - * The CsrDereferenceThread routine removes a reference from a CSR Thread. - * - * @param CsrThread - * Pointer to the CSR Thread to dereference. - * - * @return None. - * - * @remarks If the reference count has reached zero (ie: the CSR Thread has - * no more active references), it will be deleted. - * - *--*/ -VOID -NTAPI -CsrDereferenceThread(IN PCSR_THREAD CsrThread) -{ - /* Acquire process lock */ - CsrAcquireProcessLock(); - - /* Decrease reference count */ - ASSERT(CsrThread->ReferenceCount > 0); - if (!(--CsrThread->ReferenceCount)) - { - /* Call the generic cleanup code */ - CsrThreadRefcountZero(CsrThread); - } - else - { - /* Just release the lock */ - CsrReleaseProcessLock(); - } -} - -/*++ - * @name CsrExecServerThread - * @implemented NT4 - * - * The CsrExecServerThread routine creates an NT Thread and then - * initializes a CSR Thread for it. - * - * @param ThreadHandler - * Pointer to the thread's startup routine. - * - * @param Flags - * Initial CSR Thread Flags to set to the CSR Thread. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks This routine is similar to CsrAddStaticServerThread, but it - * also creates an NT Thread instead of expecting one to already - * exist. - * - *--*/ -NTSTATUS -NTAPI -CsrExecServerThread(IN PVOID ThreadHandler, - IN ULONG Flags) -{ - PCSR_THREAD CsrThread; - HANDLE hThread; - CLIENT_ID ClientId; - NTSTATUS Status; - - /* Acquire process lock */ - CsrAcquireProcessLock(); - - /* Allocate a CSR Thread in the Root Process */ - ASSERT(CsrRootProcess != NULL); - CsrThread = CsrAllocateThread(CsrRootProcess); - if (!CsrThread) - { - /* Fail */ - CsrReleaseProcessLock(); - return STATUS_NO_MEMORY; - } - - /* Create the Thread */ - Status = RtlCreateUserThread(NtCurrentProcess(), - NULL, - FALSE, - 0, - 0, - 0, - ThreadHandler, - NULL, - &hThread, - &ClientId); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - CsrDeallocateThread(CsrThread); - CsrReleaseProcessLock(); - return Status; - } - - /* Setup the Thread Object */ - CsrThread->ThreadHandle = hThread; - ProtectHandle(hThread); - CsrThread->ClientId = ClientId; - CsrThread->Flags = Flags; - - /* Insert it into the Thread List */ - InsertHeadList(&CsrRootProcess->ThreadList, &CsrThread->Link); - - /* Increase the thread count */ - CsrRootProcess->ThreadCount++; - - /* Return */ - CsrReleaseProcessLock(); - return Status; -} - -/*++ - * @name CsrDestroyThread - * @implemented NT4 - * - * 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. - * - * @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING - * if the CSR Thread is already terminating. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrDestroyThread(IN PCLIENT_ID Cid) -{ - CLIENT_ID ClientId = *Cid; - PCSR_THREAD CsrThread; - PCSR_PROCESS CsrProcess; - - /* Acquire lock */ - CsrAcquireProcessLock(); - - /* Find the thread */ - CsrThread = CsrLocateThreadByClientId(&CsrProcess, - &ClientId); - - /* Make sure we got one back, and that it's not already gone */ - if (!CsrThread || CsrThread->Flags & CsrThreadTerminated) - { - /* Release the lock and return failure */ - CsrReleaseProcessLock(); - return STATUS_THREAD_IS_TERMINATING; - } - - /* Set the terminated flag */ - CsrThread->Flags |= CsrThreadTerminated; - - /* Acquire the Wait Lock */ - CsrAcquireWaitLock(); - - /* Do we have an active wait block? */ - if (CsrThread->WaitBlock) - { - /* Notify waiters of termination */ - CsrNotifyWaitBlock(CsrThread->WaitBlock, - NULL, - NULL, - NULL, - CsrProcessTerminating, - TRUE); - } - - /* Release the Wait Lock */ - CsrReleaseWaitLock(); - - /* Dereference the thread */ - CsrLockedDereferenceThread(CsrThread); - - /* Release the Process Lock and return success */ - CsrReleaseProcessLock(); - return STATUS_SUCCESS; -} - -/*++ - * @name CsrImpersonateClient - * @implemented NT4 - * - * The CsrImpersonateClient will impersonate the given CSR Thread. - * - * @param CsrThread - * Pointer to the CSR Thread to impersonate. - * - * @return TRUE if impersionation suceeded, false otherwise. - * - * @remarks Impersonation can be recursive. - * - *--*/ -BOOLEAN -NTAPI -CsrImpersonateClient(IN PCSR_THREAD CsrThread) -{ - NTSTATUS Status; - PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; - - /* Use the current thread if none given */ - if (!CsrThread) CsrThread = CurrentThread; - - /* Still no thread, something is wrong */ - if (!CsrThread) return FALSE; - - /* Make the call */ - Status = NtImpersonateThread(NtCurrentThread(), - CsrThread->ThreadHandle, - &CsrSecurityQos); - if (!NT_SUCCESS(Status)) - { - 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 and return */ - if (CurrentThread) ++CurrentThread->ImpersonationCount; - return TRUE; -} - -/*++ - * @name CsrRevertToSelf - * @implemented NT4 - * - * The CsrRevertToSelf routine will attempt to remove an active impersonation. - * - * @param None. - * - * @return TRUE if the reversion was succesful, false otherwise. - * - * @remarks Impersonation can be recursive; as such, the impersonation token - * will only be deleted once the CSR Thread's impersonaton count - * has reached zero. - * - *--*/ -BOOLEAN -NTAPI -CsrRevertToSelf(VOID) -{ - NTSTATUS Status; - PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread; - HANDLE ImpersonationToken = NULL; - - /* Check if we have a Current Thread */ - if (CurrentThread) - { - /* Make sure impersonation is on */ - if (!CurrentThread->ImpersonationCount) - { - DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n"); - DbgBreakPoint(); - return FALSE; - } - else if (--CurrentThread->ImpersonationCount > 0) - { - /* Success; impersonation count decreased but still not zero */ - return TRUE; - } - } - - /* Impersonation has been totally removed, revert to ourselves */ - Status = NtSetInformationThread(NtCurrentThread(), - ThreadImpersonationToken, - &ImpersonationToken, - sizeof(HANDLE)); - - /* Return TRUE or FALSE */ - ASSERT(NT_SUCCESS(Status)); - return NT_SUCCESS(Status); -} - -/*++ - * @name CsrLockThreadByClientId - * @implemented NT4 - * - * The CsrLockThreadByClientId routine locks the CSR Thread corresponding - * to the given Thread ID and optionally returns it. - * - * @param Tid - * Thread ID corresponding to the CSR Thread which will be locked. - * - * @param CsrThread - * Optional pointer to a CSR Thread pointer which will hold the - * CSR Thread corresponding to the given Thread ID. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * othwerwise. - * - * @remarks Locking a CSR Thread is defined as acquiring an extra - * reference to it and returning with the Process Lock held. - * - *--*/ -NTSTATUS -NTAPI -CsrLockThreadByClientId(IN HANDLE Tid, - OUT PCSR_THREAD *CsrThread) -{ - PLIST_ENTRY NextEntry; - PCSR_THREAD CurrentThread = NULL; - NTSTATUS Status = STATUS_UNSUCCESSFUL; - ULONG i; - - /* Acquire the lock */ - CsrAcquireProcessLock(); - - /* Assume failure */ - ASSERT(CsrThread != NULL); - *CsrThread = NULL; - - /* Convert to Hash */ - i = CsrHashThread(Tid); - - /* Setup the List Pointers */ - NextEntry = CsrThreadHashTable[i].Flink; - - /* Start Loop */ - while (NextEntry != &CsrThreadHashTable[i]) - { - /* Get the Process */ - CurrentThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); - - /* Check for PID Match */ - if ((CurrentThread->ClientId.UniqueThread == Tid) && - !(CurrentThread->Flags & CsrThreadTerminated)) - { - /* Get out of here */ - break; - } - - /* Next entry */ - NextEntry = NextEntry->Flink; - } - - /* Nothing found if we got back to the list */ - if (NextEntry == &CsrThreadHashTable[i]) CurrentThread = NULL; - - /* Did the loop find something? */ - 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 */ - return Status; -} - -/*++ - * @name CsrReferenceThread - * @implemented NT4 - * - * 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. - * - * @return None. - * - * @remarks Do not use this routine if the Process Lock is already held. - * - *--*/ -VOID -NTAPI -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++; - - /* Release the lock */ - CsrReleaseProcessLock(); -} - -/*++ - * @name CsrUnlockThread - * @implemented NT4 - * - * The CsrUnlockThread undoes a previous CsrLockThreadByClientId operation. - * - * @param CsrThread - * Pointer to a previously locked CSR Thread. - * - * @return STATUS_SUCCESS. - * - * @remarks This routine must be called with the Process Lock held. - * - *--*/ -NTSTATUS -NTAPI -CsrUnlockThread(PCSR_THREAD CsrThread) -{ - /* Dereference the Thread */ - ASSERT(ProcessStructureListLocked()); - CsrLockedDereferenceThread(CsrThread); - - /* Release the lock and return */ - CsrReleaseProcessLock(); - return STATUS_SUCCESS; -} - -/* EOF */ diff --git a/subsystems/csr/csrsrv/wait.c b/subsystems/csr/csrsrv/wait.c deleted file mode 100644 index 00d0bdf3108..00000000000 --- a/subsystems/csr/csrsrv/wait.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System - * FILE: subsys/csr/csrsrv/wait.c - * PURPOSE: CSR Server DLL Wait Implementation - * PROGRAMMERS: Emanuele Aliberti - * Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES ******************************************************************/ - -#include "srv.h" - -#define NDEBUG -#include - -/* DATA **********************************************************************/ - -RTL_CRITICAL_SECTION CsrWaitListsLock; - -/* PRIVATE FUNCTIONS *********************************************************/ - -/*++ - * @name CsrInitializeWait - * - * The CsrInitializeWait routine initializes a CSR Wait Object. - * - * @param WaitFunction - * Pointer to the function that will handle this wait. - * - * @param CsrWaitThread - * Pointer to the CSR Thread that will perform the wait. - * - * @param WaitApiMessage - * Pointer to the CSR API Message associated to this wait. - * - * @param WaitContext - * Pointer to a user-defined parameter associated to this wait. - * - * @param NewWaitBlock - * Pointed to the initialized CSR Wait Block for this wait. - * - * @return TRUE in case of success, FALSE othwerwise. - * - * @remarks None. - * - *--*/ -BOOLEAN -NTAPI -CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction, - IN PCSR_THREAD CsrWaitThread, - IN OUT PCSR_API_MESSAGE WaitApiMessage, - IN PVOID WaitContext, - OUT PCSR_WAIT_BLOCK *NewWaitBlock) -{ - ULONG Size; - PCSR_WAIT_BLOCK WaitBlock; - - /* Calculate the size of the wait block */ - Size = sizeof(CSR_WAIT_BLOCK) - - sizeof(WaitBlock->WaitApiMessage) + - WaitApiMessage->Header.u1.s1.TotalLength; - - /* Allocate the Wait Block */ - WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size); - if (!WaitBlock) - { - /* Fail */ - WaitApiMessage->Status = STATUS_NO_MEMORY; - return FALSE; - } - - /* Initialize it */ - WaitBlock->Size = Size; - WaitBlock->WaitThread = CsrWaitThread; - WaitBlock->WaitContext = WaitContext; - WaitBlock->WaitFunction = WaitFunction; - WaitBlock->UserWaitList.Flink = NULL; - WaitBlock->UserWaitList.Blink = NULL; - WaitBlock->WaitList = WaitBlock->UserWaitList; - - /* Copy the message */ - RtlMoveMemory(&WaitBlock->WaitApiMessage, - WaitApiMessage, - WaitApiMessage->Header.u1.s1.TotalLength); - - /* Return the block */ - *NewWaitBlock = WaitBlock; - return TRUE; -} - -/*++ - * @name CsrNotifyWaitBlock - * - * The CsrNotifyWaitBlock routine calls the wait function for a registered - * CSR Wait Block, and replies to the attached CSR API Message, if any. - * - * @param WaitBlock - * Pointer to the CSR Wait Block - * - * @param WaitList - * Pointer to the wait list for this wait. - * - * @param WaitArgument[1-2] - * User-defined values to pass to the wait function. - * - * @param WaitFlags - * Wait flags for this wait. - * - * @param DereferenceThread - * Specifies whether the CSR Thread should be dereferenced at the - * end of this wait. - * - * @return TRUE in case of success, FALSE otherwise. - * - * @remarks After a wait block is notified, the wait function becomes invalid. - * - *--*/ -BOOLEAN -NTAPI -CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock, - IN PLIST_ENTRY WaitList, - IN PVOID WaitArgument1, - IN PVOID WaitArgument2, - IN ULONG WaitFlags, - IN BOOLEAN DereferenceThread) -{ - /* Call the wait function */ - if ((WaitBlock->WaitFunction)(WaitList, - WaitBlock->WaitThread, - &WaitBlock->WaitApiMessage, - WaitBlock->WaitContext, - WaitArgument1, - WaitArgument2, - WaitFlags)) - { - /* The wait is done, clear the block */ - WaitBlock->WaitThread->WaitBlock = NULL; - - /* Check for captured arguments */ - if (WaitBlock->WaitApiMessage.CsrCaptureData) - { - /* Release them */ - CsrReleaseCapturedArguments(&WaitBlock->WaitApiMessage); - } - - /* Reply to the port */ - NtReplyPort(WaitBlock->WaitThread->Process->ClientPort, - (PPORT_MESSAGE)&WaitBlock->WaitApiMessage); - - /* Check if we should dereference the thread */ - if (DereferenceThread) - { - /* Remove it from the Wait List */ - if (WaitBlock->WaitList.Flink) - { - RemoveEntryList(&WaitBlock->WaitList); - } - - /* Remove it from the User Wait List */ - if (WaitBlock->UserWaitList.Flink) - { - RemoveEntryList(&WaitBlock->UserWaitList); - } - - /* Dereference teh thread */ - CsrDereferenceThread(WaitBlock->WaitThread); - - /* Free the wait block */ - RtlFreeHeap(CsrHeap, 0, WaitBlock); - } - else - { - /* The wait is complete, but the thread is being kept alive */ - WaitBlock->WaitFunction = NULL; - } - - /* The wait suceeded */ - return TRUE; - } - - /* The wait failed */ - return FALSE; -} - -/* PUBLIC FUNCTIONS **********************************************************/ - -/*++ - * @name CsrCreateWait - * @implemented NT4 - * - * The CsrCreateWait routine creates a CSR Wait. - * - * @param WaitList - * Pointer to a list entry of the waits to associate. - * - * @param WaitFunction - * Pointer to the function that will handle this wait. - * - * @param CsrWaitThread - * Pointer to the CSR Thread that will perform the wait. - * - * @param WaitApiMessage - * Pointer to the CSR API Message associated to this wait. - * - * @param WaitContext - * Pointer to a user-defined parameter associated to this wait. - * - * @param UserWaitList - * Pointer to a list entry of the user-defined waits to associate. - * - * @return TRUE in case of success, FALSE otherwise. - * - * @remarks None. - * - *--*/ -BOOLEAN -NTAPI -CsrCreateWait(IN PLIST_ENTRY WaitList, - IN CSR_WAIT_FUNCTION WaitFunction, - IN PCSR_THREAD CsrWaitThread, - IN OUT PCSR_API_MESSAGE WaitApiMessage, - IN PVOID WaitContext, - IN PLIST_ENTRY UserWaitList OPTIONAL) -{ - PCSR_WAIT_BLOCK WaitBlock; - - /* Initialize the wait */ - if (!CsrInitializeWait(WaitFunction, - CsrWaitThread, - WaitApiMessage, - WaitContext, - &WaitBlock)) - { - return FALSE; - } - - /* Acquire the Wait Lock */ - CsrAcquireWaitLock(); - - /* Make sure the thread wasn't destroyed */ - if (CsrWaitThread->Flags & CsrThreadTerminated) - { - /* Fail the wait */ - RtlFreeHeap(CsrHeap, 0, WaitBlock); - CsrReleaseWaitLock(); - return FALSE; - } - - /* Insert the wait in the queue */ - InsertTailList(WaitList, &WaitBlock->WaitList); - - /* Insert the User Wait too, if one was given */ - if (UserWaitList) InsertTailList(UserWaitList, &WaitBlock->UserWaitList); - - /* Return */ - CsrReleaseWaitLock(); - return TRUE; -} - -/*++ - * @name CsrDereferenceWait - * @implemented NT4 - * - * The CsrDereferenceWait routine derefences a CSR Wait Block. - * - * @param WaitList - * Pointer to the Wait List associated to the wait. - - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrDereferenceWait(IN PLIST_ENTRY WaitList) -{ - PLIST_ENTRY NextEntry; - PCSR_WAIT_BLOCK WaitBlock; - - /* Acquire the Process and Wait Locks */ - CsrAcquireProcessLock(); - CsrAcquireWaitLock(); - - /* Set the list pointers */ - NextEntry = WaitList->Flink; - - /* Start the loop */ - while (NextEntry != WaitList) - { - /* Get the wait block */ - WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList); - - /* Move to the next entry */ - NextEntry = NextEntry->Flink; - - /* Check if there's no Wait Routine */ - if (!WaitBlock->WaitFunction) - { - /* Remove it from the Wait List */ - if (WaitBlock->WaitList.Flink) - { - RemoveEntryList(&WaitBlock->WaitList); - } - - /* Remove it from the User Wait List */ - if (WaitBlock->UserWaitList.Flink) - { - RemoveEntryList(&WaitBlock->UserWaitList); - } - - /* Dereference the thread waiting on it */ - CsrDereferenceThread(WaitBlock->WaitThread); - - /* Free the block */ - RtlFreeHeap(CsrHeap, 0, WaitBlock); - } - } - - /* Release the locks */ - CsrReleaseWaitLock(); - CsrReleaseProcessLock(); -} - -/*++ - * @name CsrMoveSatisfiedWait - * @implemented NT5 - * - * The CsrMoveSatisfiedWait routine moves satisfied waits from a wait list - * to another list entry. - * - * @param NewEntry - * Pointer to a list entry where the satisfied waits will be added. - * - * @param WaitList - * Pointer to a list entry to analyze for satisfied waits. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry, - IN PLIST_ENTRY WaitList) -{ - PLIST_ENTRY NextEntry; - PCSR_WAIT_BLOCK WaitBlock; - - /* Acquire the Wait Lock */ - CsrAcquireWaitLock(); - - /* Set the List pointers */ - NextEntry = WaitList->Flink; - - /* Start looping */ - while (NextEntry != WaitList) - { - /* Get the Wait block */ - WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList); - - /* Go to the next entry */ - NextEntry = NextEntry->Flink; - - /* Check if there is a Wait Callback */ - if (WaitBlock->WaitFunction) - { - /* Remove it from the Wait Block Queue */ - RemoveEntryList(&WaitBlock->WaitList); - - /* Insert the new entry */ - InsertTailList(&WaitBlock->WaitList, NewEntry); - } - } - - /* Release the wait lock */ - CsrReleaseWaitLock(); -} - -/*++ - * @name CsrNotifyWait - * @implemented NT4 - * - * The CsrNotifyWait notifies a CSR Wait Block. - * - * @param WaitList - * Pointer to the list entry for this wait. - * - * @param WaitType - * Type of the wait to perform, either WaitAny or WaitAll. - * - * @param WaitArgument[1-2] - * User-defined argument to pass on to the wait function. - * - * @return TRUE in case of success, FALSE othwerwise. - * - * @remarks None. - * - *--*/ -BOOLEAN -NTAPI -CsrNotifyWait(IN PLIST_ENTRY WaitList, - IN ULONG WaitType, - IN PVOID WaitArgument1, - IN PVOID WaitArgument2) -{ - PLIST_ENTRY NextEntry; - PCSR_WAIT_BLOCK WaitBlock; - BOOLEAN NotifySuccess = FALSE; - - /* Acquire the Wait Lock */ - CsrAcquireWaitLock(); - - /* Set the List pointers */ - NextEntry = WaitList->Flink; - - /* Start looping */ - while (NextEntry != WaitList) - { - /* Get the Wait block */ - WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList); - - /* Go to the next entry */ - NextEntry = NextEntry->Flink; - - /* Check if there is a Wait Callback */ - if (WaitBlock->WaitFunction) - { - /* Notify the Waiter */ - NotifySuccess |= CsrNotifyWaitBlock(WaitBlock, - WaitList, - WaitArgument1, - WaitArgument2, - 0, - FALSE); - - /* We've already done a wait, so leave unless this is a Wait All */ - if (WaitType != WaitAll) break; - } - } - - /* Release the wait lock and return */ - CsrReleaseWaitLock(); - return NotifySuccess; -} - -/* EOF */ diff --git a/subsystems/csr/main.c b/subsystems/csr/main.c deleted file mode 100644 index 301ff50084e..00000000000 --- a/subsystems/csr/main.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System - * FILE: subsys/csr/csrss.c - * PURPOSE: CSR Executable - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES ******************************************************************/ - -#define WIN32_NO_STATUS -#include -#define NTOS_MODE_USER -#include -#include - -#define NDEBUG -#include - -/* PRIVATE FUNCTIONS *********************************************************/ - -VOID -NTAPI -CsrpSetDefaultProcessHardErrorMode (VOID) -{ - ULONG DefaultHardErrorMode = 0; - - /* Disable hard errors */ - NtSetInformationProcess(NtCurrentProcess(), - ProcessDefaultHardErrorMode, - &DefaultHardErrorMode, - sizeof(DefaultHardErrorMode)); -} - -/* - * Note: Standard entrypoint for Native C Programs. - * The OS backend (NtProcessStartup) which calls this routine is - * implemented in a CRT-like static library (much like mainCRTStartup). - * Do NOT manually add the NtProcessStartup entrypoint or anything else. - */ -int -_cdecl -_main(int argc, - char *argv[], - char *envp[], - int DebugFlag) -{ - KPRIORITY BasePriority = (8 + 1) + 4; - NTSTATUS Status; - ULONG Response; - UNREFERENCED_PARAMETER(envp); - UNREFERENCED_PARAMETER(DebugFlag); - - /* Set the Priority */ - NtSetInformationProcess(NtCurrentProcess(), - ProcessBasePriority, - &BasePriority, - sizeof(KPRIORITY)); - - /* Give us IOPL so that we can access the VGA registers */ - Status = NtSetInformationProcess(NtCurrentProcess(), - ProcessUserModeIOPL, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - /* Raise a hard error */ - DPRINT1("CSRSS: Could not raise IOPL: %x\n", Status); - Status = NtRaiseHardError(STATUS_IO_PRIVILEGE_FAILED, - 0, - 0, - NULL, - OptionOk, - &Response); - } - - /* Initialize CSR through CSRSRV */ - Status = CsrServerInitialization(argc, argv); - if (!NT_SUCCESS(Status)) - { - /* Kill us */ - DPRINT1("CSRSS: CsrServerInitialization failed:% lx\n", Status); - NtTerminateProcess(NtCurrentProcess(), Status); - } - - /* Disable errors */ - CsrpSetDefaultProcessHardErrorMode(); - - /* If this is Session 0, make sure killing us bugchecks the system */ - if (!NtCurrentPeb()->SessionId) RtlSetProcessIsCritical(TRUE, NULL, FALSE); - - /* Kill this thread. CSRSRV keeps us going */ - NtTerminateThread(NtCurrentThread(), Status); - return 0; -} - -/* EOF */