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