From f40ade26d9907be8a112baee92ed18dd831345e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 20 Oct 2012 13:00:41 +0000 Subject: [PATCH] [CSRSS/CSRSRV] - Rename ProcessDataLock to CsrProcessLock (as it was in the "old" csrsrv, see r57579). - Merge the APIs from the "old" csrsrv (subsystems/csr , see r57579) with the other ones (subsystems/win32/csrss/csrsrv). - Reorganize the functions into Private & Public functions. - Add temporary comments. - Start removing things which should be present in basesrv instead of in csrsrv. This breaks build of this branch at the moment... svn path=/branches/ros-csrss/; revision=57580 --- subsystems/win32/csrss/CMakeLists.txt | 3 +- subsystems/win32/csrss/csrsrv/api/wapi.c | 265 ----- subsystems/win32/csrss/csrsrv/csrsrv.spec | 54 +- subsystems/win32/csrss/csrsrv/init.c | 64 +- subsystems/win32/csrss/csrsrv/procsup.c | 1263 ++++++++++++--------- subsystems/win32/csrss/csrsrv/session.c | 35 +- subsystems/win32/csrss/csrsrv/thredsup.c | 468 ++++++-- subsystems/win32/csrss/csrss.c | 10 +- subsystems/win32/csrss/include/api.h | 8 +- 9 files changed, 1227 insertions(+), 943 deletions(-) diff --git a/subsystems/win32/csrss/CMakeLists.txt b/subsystems/win32/csrss/CMakeLists.txt index 649f95ab82c..ca8a5778429 100644 --- a/subsystems/win32/csrss/CMakeLists.txt +++ b/subsystems/win32/csrss/CMakeLists.txt @@ -1,8 +1,7 @@ include_directories( include - ${REACTOS_SOURCE_DIR}/include/reactos/subsys - ${REACTOS_SOURCE_DIR}/include/reactos/drivers) + ${REACTOS_SOURCE_DIR}/include/reactos/subsys) add_executable(csrss csrss.c csrss.rc) diff --git a/subsystems/win32/csrss/csrsrv/api/wapi.c b/subsystems/win32/csrss/csrsrv/api/wapi.c index cd2fa0c6ce3..271710ca97c 100644 --- a/subsystems/win32/csrss/csrsrv/api/wapi.c +++ b/subsystems/win32/csrss/csrsrv/api/wapi.c @@ -489,271 +489,6 @@ CreateBaseAcls(OUT PACL* Dacl, return Status; } -VOID -WINAPI -BasepFakeStaticServerData(VOID) -{ - NTSTATUS Status; - WCHAR Buffer[MAX_PATH]; - PWCHAR HeapBuffer; - UNICODE_STRING SystemRootString; - UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%"); - UNICODE_STRING BaseSrvCSDString; - UNICODE_STRING BaseSrvWindowsDirectory; - UNICODE_STRING BaseSrvWindowsSystemDirectory; - UNICODE_STRING BnoString; - OBJECT_ATTRIBUTES ObjectAttributes; - ULONG SessionId; - HANDLE BaseSrvNamedObjectDirectory; - HANDLE BaseSrvRestrictedObjectDirectory; - PACL BnoDacl, BnoRestrictedDacl; - PSECURITY_DESCRIPTOR BnoSd; - HANDLE SymHandle; - UNICODE_STRING DirectoryName, SymlinkName; - ULONG LuidEnabled; - RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] = - { - { - NULL, - RTL_QUERY_REGISTRY_DIRECT, - L"CSDVersion", - &BaseSrvCSDString - }, - {0} - }; - - /* Get the session ID */ - SessionId = NtCurrentPeb()->SessionId; - - /* Get the Windows directory */ - RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer)); - Status = RtlExpandEnvironmentStrings_U(NULL, - &UnexpandedSystemRootString, - &SystemRootString, - NULL); - ASSERT(NT_SUCCESS(Status)); - - /* Create the base directory */ - Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL; - Status = RtlCreateUnicodeString(&BaseSrvWindowsDirectory, - SystemRootString.Buffer); - ASSERT(NT_SUCCESS(Status)); - - /* Create the system directory */ - wcscat(SystemRootString.Buffer, L"\\system32"); - Status = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory, - SystemRootString.Buffer); - ASSERT(NT_SUCCESS(Status)); - - /* FIXME: Check Session ID */ - wcscpy(Buffer, L"\\BaseNamedObjects"); - RtlInitUnicodeString(&BnoString, Buffer); - - /* Allocate the server data */ - BaseStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap, - HEAP_ZERO_MEMORY, - sizeof(BASE_STATIC_SERVER_DATA)); - ASSERT(BaseStaticServerData != NULL); - - /* Process timezone information */ - BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID; - BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0; - Status = NtQuerySystemInformation(SystemTimeOfDayInformation, - &BaseStaticServerData->TimeOfDay, - sizeof(BaseStaticServerData->TimeOfDay), - NULL); - ASSERT(NT_SUCCESS(Status)); - - /* Make a shared heap copy of the Windows directory */ - BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory; - HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap, - 0, - BaseSrvWindowsDirectory.MaximumLength); - ASSERT(HeapBuffer); - RtlCopyMemory(HeapBuffer, - BaseStaticServerData->WindowsDirectory.Buffer, - BaseSrvWindowsDirectory.MaximumLength); - BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer; - - /* Make a shared heap copy of the System directory */ - BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory; - HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap, - 0, - BaseSrvWindowsSystemDirectory.MaximumLength); - ASSERT(HeapBuffer); - RtlCopyMemory(HeapBuffer, - BaseStaticServerData->WindowsSystemDirectory.Buffer, - BaseSrvWindowsSystemDirectory.MaximumLength); - BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer; - - /* This string is not used */ - RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory, - NULL, - 0); - - /* Make a shared heap copy of the BNO directory */ - BaseStaticServerData->NamedObjectDirectory = BnoString; - BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length + - sizeof(UNICODE_NULL); - HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap, - 0, - BaseStaticServerData->NamedObjectDirectory.MaximumLength); - ASSERT(HeapBuffer); - RtlCopyMemory(HeapBuffer, - BaseStaticServerData->NamedObjectDirectory.Buffer, - BaseStaticServerData->NamedObjectDirectory.MaximumLength); - BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer; - - /* - * Confirmed that in Windows, CSDNumber and RCNumber are actually Length - * and MaximumLength of the CSD String, since the same UNICODE_STRING is - * being queried twice, the first time as a ULONG! - * - * Somehow, in Windows this doesn't cause a buffer overflow, but it might - * in ReactOS, so this code is disabled until someone figures out WTF. - */ - BaseStaticServerData->CSDNumber = 0; - BaseStaticServerData->RCNumber = 0; - - /* Initialize the CSD string and query its value from the registry */ - RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer)); - Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT, - L"", - BaseServerRegistryConfigurationTable, - NULL, - NULL); - if (NT_SUCCESS(Status)) - { - /* Copy into the shared buffer */ - wcsncpy(BaseStaticServerData->CSDVersion, - BaseSrvCSDString.Buffer, - BaseSrvCSDString.Length / sizeof(WCHAR)); - } - else - { - /* NULL-terminate to indicate nothing is there */ - BaseStaticServerData->CSDVersion[0] = UNICODE_NULL; - } - - /* Cache the system information */ - Status = NtQuerySystemInformation(SystemBasicInformation, - &BaseStaticServerData->SysInfo, - sizeof(BaseStaticServerData->SysInfo), - NULL); - ASSERT(NT_SUCCESS(Status)); - - /* FIXME: Should query the registry for these */ - BaseStaticServerData->DefaultSeparateVDM = FALSE; - BaseStaticServerData->IsWowTaskReady = FALSE; - - /* Allocate a security descriptor and create it */ - BnoSd = RtlAllocateHeap(CsrHeap, 0, 1024); - ASSERT(BnoSd); - Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION); - ASSERT(NT_SUCCESS(Status)); - - /* Create the BNO and \Restricted DACLs */ - Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl); - ASSERT(NT_SUCCESS(Status)); - - /* Set the BNO DACL as active for now */ - Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE); - ASSERT(NT_SUCCESS(Status)); - - /* Create the BNO directory */ - RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects"); - InitializeObjectAttributes(&ObjectAttributes, - &BnoString, - OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, - NULL, - BnoSd); - Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - ASSERT(NT_SUCCESS(Status)); - - /* Check if we are session 0 */ - if (!SessionId) - { - /* Mark this as a session 0 directory */ - Status = NtSetInformationObject(BaseSrvNamedObjectDirectory, - ObjectSessionInformation, - NULL, - 0); - ASSERT(NT_SUCCESS(Status)); - } - - /* Check if LUID device maps are enabled */ - Status = NtQueryInformationProcess(NtCurrentProcess(), - ProcessLUIDDeviceMapsEnabled, - &LuidEnabled, - sizeof(LuidEnabled), - NULL); - ASSERT(NT_SUCCESS(Status)); - BaseStaticServerData->LUIDDeviceMapsEnabled = LuidEnabled; - if (!BaseStaticServerData->LUIDDeviceMapsEnabled) - { - /* Make Global point back to BNO */ - RtlInitUnicodeString(&DirectoryName, L"Global"); - RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects"); - InitializeObjectAttributes(&ObjectAttributes, - &DirectoryName, - OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, - BaseSrvNamedObjectDirectory, - BnoSd); - Status = NtCreateSymbolicLinkObject(&SymHandle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes, - &SymlinkName); - if ((NT_SUCCESS(Status)) && !(SessionId)) NtClose(SymHandle); - - /* Make local point back to \Sessions\x\BNO */ - RtlInitUnicodeString(&DirectoryName, L"Local"); - ASSERT(SessionId == 0); - InitializeObjectAttributes(&ObjectAttributes, - &DirectoryName, - OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, - BaseSrvNamedObjectDirectory, - BnoSd); - Status = NtCreateSymbolicLinkObject(&SymHandle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes, - &SymlinkName); - if ((NT_SUCCESS(Status)) && !(SessionId)) NtClose(SymHandle); - - /* Make Session point back to BNOLINKS */ - RtlInitUnicodeString(&DirectoryName, L"Session"); - RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS"); - InitializeObjectAttributes(&ObjectAttributes, - &DirectoryName, - OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, - BaseSrvNamedObjectDirectory, - BnoSd); - Status = NtCreateSymbolicLinkObject(&SymHandle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes, - &SymlinkName); - if ((NT_SUCCESS(Status)) && !(SessionId)) NtClose(SymHandle); - - /* Create the BNO\Restricted directory and set the restricted DACL */ - RtlInitUnicodeString(&DirectoryName, L"Restricted"); - Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE); - ASSERT(NT_SUCCESS(Status)); - InitializeObjectAttributes(&ObjectAttributes, - &DirectoryName, - OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, - BaseSrvNamedObjectDirectory, - BnoSd); - Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - ASSERT(NT_SUCCESS(Status)); - } - - /* Finally, set the pointer */ - CsrSrvSharedStaticServerData[CSR_CONSOLE] = BaseStaticServerData; -} - NTSTATUS WINAPI CsrpHandleConnectionRequest(PPORT_MESSAGE Request) { diff --git a/subsystems/win32/csrss/csrsrv/csrsrv.spec b/subsystems/win32/csrss/csrsrv/csrsrv.spec index 19f442849c5..32fb504c63f 100644 --- a/subsystems/win32/csrss/csrsrv/csrsrv.spec +++ b/subsystems/win32/csrss/csrsrv/csrsrv.spec @@ -1,36 +1,36 @@ @ stdcall CsrAddStaticServerThread(ptr ptr long) @ stdcall CsrCallServerFromServer(ptr ptr) -;@ stdcall CsrConnectToUser() -;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr) +@ stdcall CsrConnectToUser() +@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr) @ stdcall CsrCreateRemoteThread(ptr ptr) -@ stdcall CsrCreateThread(ptr ptr ptr) -;@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr) -;@ stdcall CsrDebugProcess(ptr) -;@ stdcall CsrDebugProcessStop(ptr) -;@ stdcall CsrDereferenceProcess(ptr) -;@ stdcall CsrDereferenceThread(ptr) -;@ stdcall CsrDereferenceWait(ptr) -;@ stdcall CsrDestroyProcess(ptr long) -;@ stdcall CsrDestroyThread(ptr) -@ stdcall CsrEnumProcesses(ptr ptr) ; Temporary hack -;@ stdcall CsrExecServerThread(ptr long) +@ 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) +@ stdcall CsrDereferenceProcess(ptr) +@ stdcall CsrDereferenceThread(ptr) +@ stdcall CsrDereferenceWait(ptr) +@ stdcall CsrDestroyProcess(ptr long) +@ stdcall CsrDestroyThread(ptr) +@ stdcall CsrEnumProcesses(ptr ptr) ;;;;;;; Temporary hack used in win32csr, to be removed +@ stdcall CsrExecServerThread(ptr long) @ stdcall CsrGetProcessLuid(ptr ptr) @ stdcall CsrImpersonateClient(ptr) @ stdcall CsrLockProcessByClientId(ptr ptr) -;@ stdcall CsrLockThreadByClientId(ptr ptr) -;@ stdcall CsrMoveSatisfiedWait(ptr ptr) -;@ stdcall CsrNotifyWait(ptr long ptr ptr) -;@ stdcall CsrPopulateDosDevices() -;@ stdcall CsrQueryApiPort() -;@ stdcall CsrReferenceThread(ptr) +@ stdcall CsrLockThreadByClientId(ptr ptr) +@ stdcall CsrMoveSatisfiedWait(ptr ptr) +@ stdcall CsrNotifyWait(ptr long ptr ptr) +@ stdcall CsrPopulateDosDevices() +@ stdcall CsrQueryApiPort() +@ stdcall CsrReferenceThread(ptr) @ stdcall CsrRevertToSelf() @ stdcall CsrServerInitialization(long ptr) -;@ stdcall CsrSetBackgroundPriority(ptr) -;@ stdcall CsrSetCallingSpooler(long) -;@ stdcall CsrSetForegroundPriority(ptr) -;@ stdcall CsrShutdownProcesses(ptr long) -;@ stdcall CsrUnhandledExceptionFilter(ptr) +@ stdcall CsrSetBackgroundPriority(ptr) +@ stdcall CsrSetCallingSpooler(long) +@ stdcall CsrSetForegroundPriority(ptr) +@ stdcall CsrShutdownProcesses(ptr long) +@ stdcall CsrUnhandledExceptionFilter(ptr) @ stdcall CsrUnlockProcess(ptr) -;@ stdcall CsrUnlockThread(ptr) -;@ stdcall CsrValidateMessageBuffer(ptr ptr long long) -;@ stdcall CsrValidateMessageString(ptr ptr) +@ stdcall CsrUnlockThread(ptr) +@ stdcall CsrValidateMessageBuffer(ptr ptr long long) +@ stdcall CsrValidateMessageString(ptr ptr) diff --git a/subsystems/win32/csrss/csrsrv/init.c b/subsystems/win32/csrss/csrsrv/init.c index 45a44336cc1..af7f76a2746 100644 --- a/subsystems/win32/csrss/csrsrv/init.c +++ b/subsystems/win32/csrss/csrsrv/init.c @@ -1,6 +1,6 @@ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System + * PROJECT: ReactOS CSR SubSystem * FILE: subsystems/win32/csrss/csrsrv/init.c * PURPOSE: CSR Server DLL Initialization * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) @@ -10,6 +10,7 @@ /* INCLUDES *******************************************************************/ #include "srv.h" + #define NDEBUG #include @@ -40,7 +41,7 @@ VOID CallHardError(IN PCSR_THREAD ThreadData, IN PHARDERROR_MSG HardErrorMessage) { - unsigned i; + ULONG i; PCSR_SERVER_DLL ServerDll; DPRINT("CSR: %s called\n", __FUNCTION__); @@ -64,7 +65,7 @@ CallProcessCreated(IN PCSR_PROCESS SourceProcessData, IN PCSR_PROCESS TargetProcessData) { NTSTATUS Status = STATUS_SUCCESS; - unsigned i; + ULONG i; PCSR_SERVER_DLL ServerDll; DPRINT("CSR: %s called\n", __FUNCTION__); @@ -85,8 +86,14 @@ CallProcessCreated(IN PCSR_PROCESS SourceProcessData, return Status; } +/*** + *** Some APIs from here will go to basesrv.dll, some others to winsrv.dll. + *** Furthermore, this structure uses the old definition of APIs list. + *** The new one is in fact three arrays, one of APIs pointers, one other of + *** corresponding indexes, and the third one of names (not very efficient...). + ***/ CSRSS_API_DEFINITION NativeDefinitions[] = - { +{ CSRSS_DEFINE_API(CREATE_PROCESS, CsrSrvCreateProcess), CSRSS_DEFINE_API(CREATE_THREAD, CsrSrvCreateThread), CSRSS_DEFINE_API(TERMINATE_PROCESS, CsrTerminateProcess), @@ -95,14 +102,10 @@ CSRSS_API_DEFINITION NativeDefinitions[] = CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS, CsrGetShutdownParameters), CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS, CsrSetShutdownParameters), { 0, 0, NULL } - }; +}; /* === INIT ROUTINES === */ -VOID -WINAPI -BasepFakeStaticServerData(VOID); - /*++ * @name CsrSetProcessSecurity * @@ -640,9 +643,10 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount, ParameterValue = NULL; ParameterValue = strchr(ParameterName, '='); if (ParameterValue) *ParameterValue++ = ANSI_NULL; + DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue); /* Check for Object Directory */ - if (!_stricmp(ParameterName, "ObjectDirectory")) + if (_stricmp(ParameterName, "ObjectDirectory") == 0) { /* Check if a session ID is specified */ if (SessionId) @@ -674,26 +678,26 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount, Status = CsrSetDirectorySecurity(CsrObjectDirectory); if (!NT_SUCCESS(Status)) return Status; } - else if (!_stricmp(ParameterName, "SubSystemType")) + else if (_stricmp(ParameterName, "SubSystemType") == 0) { /* Ignored */ } - else if (!_stricmp(ParameterName, "MaxRequestThreads")) + else if (_stricmp(ParameterName, "MaxRequestThreads") == 0) { Status = RtlCharToInteger(ParameterValue, 0, &CsrMaxApiRequestThreads); } - else if (!_stricmp(ParameterName, "RequestThreads")) + else if (_stricmp(ParameterName, "RequestThreads") == 0) { /* Ignored */ Status = STATUS_SUCCESS; } - else if (!_stricmp(ParameterName, "ProfileControl")) + else if (_stricmp(ParameterName, "ProfileControl") == 0) { /* Ignored */ } - else if (!_stricmp(ParameterName, "SharedSection")) + else if (_stricmp(ParameterName, "SharedSection") == 0) { /* Create the Section */ Status = CsrSrvCreateSharedSection(ParameterValue); @@ -705,9 +709,9 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount, } /* Load us */ - Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER); + Status = CsrLoadServerDll("CSRSS" /* "CSRSRV" */, NULL, CSR_SRV_SERVER); } - else if (!_stricmp(ParameterName, "ServerDLL")) + else if (_stricmp(ParameterName, "ServerDLL") == 0) { /* Loop the command line */ EntryPoint = NULL; @@ -743,19 +747,7 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount, /* Load it */ if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint); - - /* Hackito ergo sum */ - Status = STATUS_SUCCESS; - if (strstr(ParameterValue, "basesrv")) - { - DPRINT1("Fake basesrv init\n"); - BasepFakeStaticServerData(); - } -// else -// { -// Status = CsrLoadServerDll(ParameterValue, EntryPoint, 2); -// } - // Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex); + Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n", @@ -763,9 +755,10 @@ CsrParseServerCommandLine(IN ULONG ArgumentCount, return Status; } } - else if (!_stricmp(ParameterName, "Windows")) + else if (_stricmp(ParameterName, "Windows") == 0) { /* Ignored */ + // Check whether we want to start in pure GUI or pure CLI. } else { @@ -945,6 +938,8 @@ CsrSbApiPortInitialize(VOID) return Status; } + + /* PUBLIC FUNCTIONS ***********************************************************/ /*++ @@ -1053,12 +1048,16 @@ CsrServerInitialization(IN ULONG ArgumentCount, return Status; } - /* Initialize Win32csr */ + //////////////////////////// ADDED //////////////////////////// + /* + /\* Initialize Win32csr *\/ Status = CsrLoadServerDll("win32csr", "Win32CsrInitialization", 2); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrLoadServerDll", Status); } + */ + //////////////////////////// END ADDED //////////////////////////// /* Initialize the API Port for SM communication */ Status = CsrSbApiPortInitialize(); @@ -1138,6 +1137,7 @@ DllMain(IN HANDLE hDll, UNREFERENCED_PARAMETER(hDll); UNREFERENCED_PARAMETER(dwReason); UNREFERENCED_PARAMETER(lpReserved); + return TRUE; } diff --git a/subsystems/win32/csrss/csrsrv/procsup.c b/subsystems/win32/csrss/csrsrv/procsup.c index 604c7e95d88..180892d85e2 100644 --- a/subsystems/win32/csrss/csrsrv/procsup.c +++ b/subsystems/win32/csrss/csrsrv/procsup.c @@ -1,10 +1,10 @@ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System + * PROJECT: ReactOS CSR SubSystem * FILE: subsystems/win32/csrss/csrsrv/procsup.c - * PURPOSE: CSR Process Management + * PURPOSE: CSR Server DLL Process Management * PROGRAMMERS: ReactOS Portable Systems Group - * Alex Ionescu + * Alex Ionescu (alex@relsoft.net) */ /* INCLUDES *******************************************************************/ @@ -16,7 +16,7 @@ /* GLOBALS ********************************************************************/ -RTL_CRITICAL_SECTION ProcessDataLock; +RTL_CRITICAL_SECTION CsrProcessLock; PCSR_PROCESS CsrRootProcess = NULL; SECURITY_QUALITY_OF_SERVICE CsrSecurityQos = { @@ -26,13 +26,28 @@ SECURITY_QUALITY_OF_SERVICE CsrSecurityQos = FALSE }; ULONG CsrProcessSequenceCount = 5; -extern ULONG CsrTotalPerProcessDataLength; +extern ULONG CsrTotalPerProcessDataLength; // remove 'extern' if not needed. -/* FUNCTIONS ******************************************************************/ +/* PRIVATE FUNCTIONS **********************************************************/ + +/*++ + * @name CsrpSetToNormalPriority + * + * The CsrpSetToNormalPriority routine sets the current NT Process' + * priority to the normal priority for CSR Processes. + * + * @param None. + * + * @return None. + * + * @remarks The "Normal" Priority corresponds to the Normal Forground + * Priority (9) plus a boost of 4. + * + *--*/ VOID NTAPI -CsrSetToNormalPriority(VOID) +CsrSetToNormalPriority(VOID) // CsrpSetToNormalPriority { KPRIORITY BasePriority = (8 + 1) + 4; @@ -43,9 +58,24 @@ CsrSetToNormalPriority(VOID) sizeof(KPRIORITY)); } +/*++ + * @name CsrpSetToShutdownPriority + * + * The CsrpSetToShutdownPriority routine sets the current NT Process' + * priority to the boosted priority for CSR Processes doing shutdown. + * Additonally, it acquires the Shutdown Privilege required for shutdown. + * + * @param None. + * + * @return None. + * + * @remarks The "Shutdown" Priority corresponds to the Normal Forground + * Priority (9) plus a boost of 6. + * + *--*/ VOID NTAPI -CsrSetToShutdownPriority(VOID) +CsrSetToShutdownPriority(VOID) // CsrpSetToShutdownPriority { KPRIORITY SetBasePriority = (8 + 1) + 6; BOOLEAN Old; @@ -64,6 +94,410 @@ CsrSetToShutdownPriority(VOID) } } +/*++ + * @name FindProcessForShutdown + * + * The FindProcessForShutdown routine returns a CSR Process which is ready + * to be shutdown, and sets the appropriate shutdown flags for it. + * + * @param CallerLuid + * Pointer to the LUID of the CSR Process calling this routine. + * + * @return Pointer to a CSR Process which is ready to be shutdown. + * + * @remarks None. + * + *--*/ +PCSR_PROCESS +NTAPI +FindProcessForShutdown(IN PLUID CallerLuid) +{ + PCSR_PROCESS CsrProcess, ReturnCsrProcess = NULL; + // PCSR_THREAD CsrThread; + NTSTATUS Status; + ULONG Level = 0; + LUID ProcessLuid; + LUID SystemLuid = SYSTEM_LUID; + // BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE; + PLIST_ENTRY NextEntry; + + /* Set the List Pointers */ + NextEntry = CsrRootProcess->ListLink.Flink; + while (NextEntry != &CsrRootProcess->ListLink) + { + /* Get the process */ + CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); + + /* Move to the next entry */ + NextEntry = NextEntry->Flink; + + /* Skip this process if it's already been processed */ + if (CsrProcess->Flags & CsrProcessSkipShutdown) continue; + + /* Get the LUID of this Process */ + Status = CsrGetProcessLuid(CsrProcess->ProcessHandle, &ProcessLuid); + + /* Check if we didn't get access to the LUID */ + if (Status == STATUS_ACCESS_DENIED) + { + /* FIXME: Check if we have any threads */ +/* + /\* Check if we have any threads *\/ + if (CsrProcess->ThreadCount) + { + /\* Impersonate one of the threads and retry *\/ + CsrThread = CONTAINING_RECORD(CsrProcess->ThreadList.Flink, + CSR_THREAD, + Link); + CsrImpersonateClient(CsrThread); + Status = CsrGetProcessLuid(NULL, &ProcessLuid); + CsrRevertToSelf(); + } +*/ + } + + if (!NT_SUCCESS(Status)) + { + /* We didn't have access, so skip it */ + CsrProcess->Flags |= CsrProcessSkipShutdown; + continue; + } + + /* Check if this is the System LUID */ + if ((/*IsSystemLuid =*/ RtlEqualLuid(&ProcessLuid, &SystemLuid))) + { + /* Mark this process */ + CsrProcess->ShutdownFlags |= CsrShutdownSystem; + } + else if (!(/*IsOurLuid =*/ RtlEqualLuid(&ProcessLuid, CallerLuid))) + { + /* Our LUID doesn't match with the caller's */ + CsrProcess->ShutdownFlags |= CsrShutdownOther; + } + + /* Check if we're past the previous level */ + // FIXME: if ((CsrProcess->ShutdownLevel > Level) || !(ReturnCsrProcess)) + if (CsrProcess->ShutdownLevel > Level /* || !ReturnCsrProcess */) + { + /* Update the level */ + Level = CsrProcess->ShutdownLevel; + + /* Set the final process */ + ReturnCsrProcess = CsrProcess; + } + } + + /* Check if we found a process */ + if (ReturnCsrProcess) + { + /* Skip this one next time */ + ReturnCsrProcess->Flags |= CsrProcessSkipShutdown; + } + + return ReturnCsrProcess; +} + +/*++ + * @name CsrProcessRefcountZero + * + * The CsrProcessRefcountZero routine is executed when a CSR Process has lost + * all its active references. It removes and de-allocates the CSR Process. + * + * @param CsrProcess + * Pointer to the CSR Process that is to be deleted. + * + * @return None. + * + * @remarks Do not call this routine. It is reserved for the internal + * thread management routines when a CSR Process has lost all + * its references. + * + * This routine is called with the Process Lock held. + * + *--*/ +VOID +NTAPI +CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess) +{ + ASSERT(ProcessStructureListLocked()); + + /* Remove the Process from the list */ + CsrRemoveProcess(CsrProcess); + + /* Check if there's a session */ + if (CsrProcess->NtSession) + { + /* Dereference the Session */ + CsrDereferenceNtSession(CsrProcess->NtSession, 0); + } + + /* Close the Client Port if there is one */ + if (CsrProcess->ClientPort) NtClose(CsrProcess->ClientPort); + + /* Close the process handle */ + NtClose(CsrProcess->ProcessHandle); + + /* Free the Proces Object */ + CsrDeallocateProcess(CsrProcess); +} + +/*++ + * @name CsrLockedDereferenceProcess + * + * The CsrLockedDereferenceProcess dereferences a CSR Process while the + * Process Lock is already being held. + * + * @param CsrProcess + * Pointer to the CSR Process to be dereferenced. + * + * @return None. + * + * @remarks This routine will return with the Process Lock held. + * + *--*/ +VOID +NTAPI +CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess) +{ + LONG LockCount; + + /* Decrease reference count */ + LockCount = --CsrProcess->ReferenceCount; + ASSERT(LockCount >= 0); + if (!LockCount) + { + /* Call the generic cleanup code */ + DPRINT1("Should kill process: %p\n", CsrProcess); + CsrProcessRefcountZero(CsrProcess); + CsrAcquireProcessLock(); + } +} + +/*++ + * @name CsrAllocateProcess + * @implemented NT4 + * + * The CsrAllocateProcess routine allocates a new CSR Process object. + * + * @return Pointer to the newly allocated CSR Process. + * + * @remarks None. + * + *--*/ +PCSR_PROCESS +NTAPI +CsrAllocateProcess(VOID) +{ + PCSR_PROCESS CsrProcess; + ULONG TotalSize; + + /* Calculate the amount of memory this should take */ + TotalSize = sizeof(CSR_PROCESS) + + (CSR_SERVER_DLL_MAX * sizeof(PVOID)) + + CsrTotalPerProcessDataLength; + + /* Allocate a Process */ + CsrProcess = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, TotalSize); + if (!CsrProcess) return NULL; + + /* Handle the Sequence Number and protect against overflow */ + CsrProcess->SequenceNumber = CsrProcessSequenceCount++; + if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5; + + /* Increase the reference count */ + CsrProcess->ReferenceCount++; + + /* Initialize the Thread List */ + InitializeListHead(&CsrProcess->ThreadList); + + /* Return the Process */ + return CsrProcess; +} + +/*++ + * @name CsrLockedReferenceProcess + * + * The CsrLockedReferenceProcess references 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 CsrInitializeProcessStructure + * @implemented NT4 + * + * The CsrInitializeProcessStructure routine sets up support for CSR Processes + * and CSR Threads. + * + * @param None. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * otherwise. + * + * @remarks None. + * + *--*/ +NTSTATUS +NTAPI +CsrInitializeProcessStructure(VOID) +{ + NTSTATUS Status; + ULONG i; + + /* Initialize the Lock */ + Status = RtlInitializeCriticalSection(&CsrProcessLock); + if (!NT_SUCCESS(Status)) return Status; + + /* Set up the Root Process */ + CsrRootProcess = CsrAllocateProcess(); + if (!CsrRootProcess) return STATUS_NO_MEMORY; + + /* Set up the minimal information for it */ + InitializeListHead(&CsrRootProcess->ListLink); + CsrRootProcess->ProcessHandle = (HANDLE)-1; + CsrRootProcess->ClientId = NtCurrentTeb()->ClientId; + + /* Initialize the Thread Hash List */ + for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]); + + /* Initialize the Wait Lock */ + return RtlInitializeCriticalSection(&CsrWaitListsLock); +} + +/*++ + * @name CsrDeallocateProcess + * + * The CsrDeallocateProcess frees the memory associated with a CSR Process. + * + * @param CsrProcess + * Pointer to the CSR Process to be freed. + * + * @return None. + * + * @remarks Do not call this routine. It is reserved for the internal + * thread management routines when a CSR Process has been cleanly + * dereferenced and killed. + * + *--*/ +VOID +NTAPI +CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess) +{ + /* Free the process object from the heap */ + RtlFreeHeap(CsrHeap, 0, CsrProcess); +} + +/*++ + * @name CsrRemoveProcess + * + * The CsrRemoveProcess function undoes a CsrInsertProcess operation and + * removes the CSR Process from the Process List and notifies Server DLLs + * of this removal. + * + * @param CsrProcess + * Pointer to the CSR Process to remove. + * + * @return None. + * + * @remarks None. + * + *--*/ +VOID +NTAPI +CsrRemoveProcess(IN PCSR_PROCESS CsrProcess) +{ + PCSR_SERVER_DLL ServerDll; + ULONG i; + ASSERT(ProcessStructureListLocked()); + + /* Remove us from the Process List */ + RemoveEntryList(&CsrProcess->ListLink); + + /* Release the lock */ + CsrReleaseProcessLock(); + + /* Loop every Server DLL */ + for (i = 0; i < CSR_SERVER_DLL_MAX; i++) + { + /* Get the Server DLL */ + ServerDll = CsrLoadedServerDll[i]; + + /* Check if it's valid and if it has a Disconnect Callback */ + if ((ServerDll) && (ServerDll->DisconnectCallback)) + { + /* Call it */ + ServerDll->DisconnectCallback(CsrProcess); + } + } +} + +/*++ + * @name CsrInsertProcess + * + * The CsrInsertProcess routine inserts a CSR Process into the Process List + * and notifies Server DLLs of the creation of a new CSR Process. + * + * @param Parent + * Optional pointer to the CSR Process creating this CSR Process. + * + * @param CurrentProcess + * Optional pointer to the current CSR Process. + * + * @param CsrProcess + * Pointer to the CSR Process which is to be inserted. + * + * @return None. + * + * @remarks None. + * + *--*/ +VOID +NTAPI +CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, + IN PCSR_PROCESS CurrentProcess OPTIONAL, + IN PCSR_PROCESS CsrProcess) +{ + PCSR_SERVER_DLL ServerDll; + ULONG i; + ASSERT(ProcessStructureListLocked()); + + /* Set the parent */ + CsrProcess->Parent = Parent; + + /* Insert it into the Root List */ + InsertTailList(&CsrRootProcess->ListLink, &CsrProcess->ListLink); + + /* Notify the Server DLLs */ + for (i = 0; i < CSR_SERVER_DLL_MAX; i++) + { + /* Get the current Server DLL */ + ServerDll = CsrLoadedServerDll[i]; + + /* Make sure it's valid and that it has callback */ + if ((ServerDll) && (ServerDll->NewProcessCallback)) + { + ServerDll->NewProcessCallback(CurrentProcess, CsrProcess); + } + } +} + + +/* PUBLIC FUNCTIONS ***********************************************************/ + /*++ * @name CsrGetProcessLuid * @implemented NT4 @@ -251,6 +685,7 @@ CsrRevertToSelf(VOID) if (!CurrentThread->ImpersonationCount) { // DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n"); + // DbgBreakPoint(); return FALSE; } else if (--CurrentThread->ImpersonationCount > 0) @@ -270,275 +705,6 @@ CsrRevertToSelf(VOID) return NT_SUCCESS(Status); } -/*++ - * @name FindProcessForShutdown - * - * The FindProcessForShutdown routine returns a CSR Process which is ready - * to be shutdown, and sets the appropriate shutdown flags for it. - * - * @param CallerLuid - * Pointer to the LUID of the CSR Process calling this routine. - * - * @return Pointer to a CSR Process which is ready to be shutdown. - * - * @remarks None. - * - *--*/ -PCSR_PROCESS -NTAPI -FindProcessForShutdown(IN PLUID CallerLuid) -{ - PCSR_PROCESS CsrProcess, ReturnCsrProcess = NULL; - // PCSR_THREAD CsrThread; - NTSTATUS Status; - ULONG Level = 0; - LUID ProcessLuid; - LUID SystemLuid = SYSTEM_LUID; - // BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE; - PLIST_ENTRY NextEntry; - - /* Set the List Pointers */ - NextEntry = CsrRootProcess->ListLink.Flink; - while (NextEntry != &CsrRootProcess->ListLink) - { - /* Get the process */ - CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); - - /* Move to the next entry */ - NextEntry = NextEntry->Flink; - - /* Skip this process if it's already been processed */ - if (CsrProcess->Flags & CsrProcessSkipShutdown) continue; - - /* Get the LUID of this Process */ - Status = CsrGetProcessLuid(CsrProcess->ProcessHandle, &ProcessLuid); - - /* Check if we didn't get access to the LUID */ - if (Status == STATUS_ACCESS_DENIED) - { - /* FIXME:Check if we have any threads */ -/* - if (CsrProcess->ThreadCount) - { - /\* Impersonate one of the threads and retry *\/ - CsrThread = CONTAINING_RECORD(CsrProcess->ThreadList.Flink, - CSR_THREAD, - Link); - CsrImpersonateClient(CsrThread); - Status = CsrGetProcessLuid(NULL, &ProcessLuid); - CsrRevertToSelf(); - } -*/ - } - - if (!NT_SUCCESS(Status)) - { - /* We didn't have access, so skip it */ - CsrProcess->Flags |= CsrProcessSkipShutdown; - continue; - } - - /* Check if this is the System LUID */ - if ((/*IsSystemLuid =*/ RtlEqualLuid(&ProcessLuid, &SystemLuid))) - { - /* Mark this process */ - CsrProcess->ShutdownFlags |= CsrShutdownSystem; - } - else if (!(/*IsOurLuid =*/ RtlEqualLuid(&ProcessLuid, CallerLuid))) - { - /* Our LUID doesn't match with the caller's */ - CsrProcess->ShutdownFlags |= CsrShutdownOther; - } - - /* Check if we're past the previous level */ - if (CsrProcess->ShutdownLevel > Level /* || !ReturnCsrProcess */) - { - /* Update the level */ - Level = CsrProcess->ShutdownLevel; - - /* Set the final process */ - ReturnCsrProcess = CsrProcess; - } - } - - /* Check if we found a process */ - if (ReturnCsrProcess) - { - /* Skip this one next time */ - ReturnCsrProcess->Flags |= CsrProcessSkipShutdown; - } - - return ReturnCsrProcess; -} - -/* This is really "CsrShutdownProcess", mostly */ -NTSTATUS -WINAPI -CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc, - IN PVOID Context) -{ - PVOID* RealContext = (PVOID*)Context; - PLUID CallerLuid = RealContext[0]; - PCSR_PROCESS CsrProcess = NULL; - NTSTATUS Status = STATUS_UNSUCCESSFUL; - BOOLEAN FirstTry; - PLIST_ENTRY NextEntry; - ULONG Result = 0; - - /* Acquire process lock */ - CsrAcquireProcessLock(); - - /* Get the list pointers */ - NextEntry = CsrRootProcess->ListLink.Flink; - while (NextEntry != &CsrRootProcess->ListLink) - { - /* Get the Process */ - CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); - - /* Remove the skip flag, set shutdown flags to 0*/ - CsrProcess->Flags &= ~CsrProcessSkipShutdown; - CsrProcess->ShutdownFlags = 0; - - /* Move to the next */ - NextEntry = NextEntry->Flink; - } - - /* Set shudown Priority */ - CsrSetToShutdownPriority(); - - /* Loop all processes */ - //DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart); - - /* Start looping */ - while (TRUE) - { - /* Find the next process to shutdown */ - FirstTry = TRUE; - if (!(CsrProcess = FindProcessForShutdown(CallerLuid))) - { - /* Done, quit */ - CsrReleaseProcessLock(); - Status = STATUS_SUCCESS; - goto Quickie; - } - -LoopAgain: - /* Release the lock, make the callback, and acquire it back */ - //DPRINT1("Found process: %lx\n", CsrProcess->ClientId.UniqueProcess); - CsrReleaseProcessLock(); - Result = (ULONG)EnumProc(CsrProcess, (PVOID)((ULONG_PTR)Context | FirstTry)); - CsrAcquireProcessLock(); - - /* Check the result */ - //DPRINT1("Result: %d\n", Result); - if (Result == CsrShutdownCsrProcess) - { - /* 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 */ - CsrReleaseProcessLock(); - Status = STATUS_CANCELLED; - goto Quickie; - } - - /* No matches during the first try, so loop again */ - if (FirstTry && Result == CsrShutdownNonCsrProcess) - { - FirstTry = FALSE; - goto LoopAgain; - } - } - -Quickie: - /* Return to normal priority */ - CsrSetToNormalPriority(); - return Status; -} - -/*++ - * @name CsrProcessRefcountZero - * - * The CsrProcessRefcountZero routine is executed when a CSR Process has lost - * all its active references. It removes and de-allocates the CSR Process. - * - * @param CsrProcess - * Pointer to the CSR Process that is to be deleted. - * - * @return None. - * - * @remarks Do not call this routine. It is reserved for the internal - * thread management routines when a CSR Process has lost all - * its references. - * - * This routine is called with the Process Lock held. - * - *--*/ -VOID -NTAPI -CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess) -{ - ASSERT(ProcessStructureListLocked()); - - /* Remove the Process from the list */ - CsrRemoveProcess(CsrProcess); - - /* Check if there's a session */ - if (CsrProcess->NtSession) - { - /* Dereference the Session */ - CsrDereferenceNtSession(CsrProcess->NtSession, 0); - } - - /* Close the Client Port if there is one */ - if (CsrProcess->ClientPort) NtClose(CsrProcess->ClientPort); - - /* Close the process handle */ - NtClose(CsrProcess->ProcessHandle); - - /* Free the Proces Object */ - CsrDeallocateProcess(CsrProcess); -} - -/*++ - * @name CsrLockedDereferenceProcess - * - * The CsrLockedDereferenceProcess dereferences a CSR Process while the - * Process Lock is already being held. - * - * @param CsrProcess - * Pointer to the CSR Process to be dereferenced. - * - * @return None. - * - * @remarks This routine will return with the Process Lock held. - * - *--*/ -VOID -NTAPI -CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess) -{ - LONG LockCount; - - /* Decrease reference count */ - LockCount = --CsrProcess->ReferenceCount; - ASSERT(LockCount >= 0); - if (!LockCount) - { - /* Call the generic cleanup code */ - DPRINT1("Should kill process: %p\n", CsrProcess); - CsrProcessRefcountZero(CsrProcess); - CsrAcquireProcessLock(); - } -} - /*++ * @name CsrDereferenceProcess * @implemented NT4 @@ -702,8 +868,8 @@ CsrCreateProcess(IN HANDLE hProcess, PCSR_THREAD CurrentThread = CsrGetClientThread(); CLIENT_ID CurrentCid; PCSR_PROCESS CurrentProcess; -// PVOID ProcessData; -// ULONG i; + PVOID ProcessData; + ULONG i; PCSR_PROCESS CsrProcess; NTSTATUS Status; PCSR_THREAD CsrThread; @@ -731,7 +897,6 @@ CsrCreateProcess(IN HANDLE hProcess, return STATUS_NO_MEMORY; } -#if 0 /* Inherit the Process Data */ CurrentProcess = CurrentThread->Process; ProcessData = &CurrentProcess->ServerData[CSR_SERVER_DLL_MAX]; @@ -758,9 +923,8 @@ CsrCreateProcess(IN HANDLE hProcess, CsrProcess->ServerData[i] = NULL; } } -#endif - /* Set the Exception port to us */ + /* Set the Exception port for us */ Status = NtSetInformationProcess(hProcess, ProcessExceptionPort, &CsrApiPort, @@ -773,7 +937,7 @@ CsrCreateProcess(IN HANDLE hProcess, return STATUS_NO_MEMORY; } - /* If Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */ + /* Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */ if (!(Flags & CsrProcessCreateNewGroup)) { /* Create new data */ @@ -811,10 +975,10 @@ CsrCreateProcess(IN HANDLE hProcess, CsrProcess->DebugCid = *DebugCid; } - /* Check if we debugging is enabled */ + /* Check if Debugging is enabled */ if (CsrProcess->DebugFlags) { - /* Set the Debug Port to us */ + /* Set the Debug Port for us */ Status = NtSetInformationProcess(hProcess, ProcessDebugPort, &CsrApiPort, @@ -940,231 +1104,6 @@ CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess) sizeof(PriorityClass)); } -/*++ - * @name CsrAllocateProcess - * @implemented NT4 - * - * The CsrAllocateProcess routine allocates a new CSR Process object. - * - * @return Pointer to the newly allocated CSR Process. - * - * @remarks None. - * - *--*/ -PCSR_PROCESS -NTAPI -CsrAllocateProcess(VOID) -{ - PCSR_PROCESS CsrProcess; - ULONG TotalSize; - - /* Calculate the amount of memory this should take */ - TotalSize = sizeof(CSR_PROCESS) + - (CSR_SERVER_DLL_MAX * sizeof(PVOID)) + - CsrTotalPerProcessDataLength; - - /* Allocate a Process */ - CsrProcess = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, TotalSize); - if (!CsrProcess) return NULL; - - /* Handle the Sequence Number and protect against overflow */ - CsrProcess->SequenceNumber = CsrProcessSequenceCount++; - if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5; - - /* Increase the reference count */ - CsrProcess->ReferenceCount++; - - /* Initialize the Thread List */ - InitializeListHead(&CsrProcess->ThreadList); - - /* Return the Process */ - return CsrProcess; -} - -/*++ - * @name CsrLockedReferenceProcess - * - * The CsrLockedReferenceProcess references 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 CsrInitializeProcessStructure - * @implemented NT4 - * - * The CsrInitializeProcessStructure routine sets up support for CSR Processes - * and CSR Threads. - * - * @param None. - * - * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL - * otherwise. - * - * @remarks None. - * - *--*/ -NTSTATUS -NTAPI -CsrInitializeProcessStructure(VOID) -{ - NTSTATUS Status; - ULONG i; - - /* Initialize the Lock */ - Status = RtlInitializeCriticalSection(&ProcessDataLock); - if (!NT_SUCCESS(Status)) return Status; - - /* Set up the Root Process */ - CsrRootProcess = CsrAllocateProcess(); - if (!CsrRootProcess) return STATUS_NO_MEMORY; - - /* Set up the minimal information for it */ - InitializeListHead(&CsrRootProcess->ListLink); - CsrRootProcess->ProcessHandle = (HANDLE)-1; - CsrRootProcess->ClientId = NtCurrentTeb()->ClientId; - - /* Initialize the Thread Hash List */ - for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]); - - /* Initialize the Wait Lock */ - return RtlInitializeCriticalSection(&CsrWaitListsLock); -} - -/*++ - * @name CsrDeallocateProcess - * - * The CsrDeallocateProcess frees the memory associated with a CSR Process. - * - * @param CsrProcess - * Pointer to the CSR Process to be freed. - * - * @return None. - * - * @remarks Do not call this routine. It is reserved for the internal - * thread management routines when a CSR Process has been cleanly - * dereferenced and killed. - * - *--*/ -VOID -NTAPI -CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess) -{ - /* Free the process object from the heap */ - RtlFreeHeap(CsrHeap, 0, CsrProcess); -} - -/*++ - * @name CsrRemoveProcess - * - * The CsrRemoveProcess function undoes a CsrInsertProcess operation and - * removes the CSR Process from the Process List and notifies Server DLLs - * of this removal. - * - * @param CsrProcess - * Pointer to the CSR Process to remove. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrRemoveProcess(IN PCSR_PROCESS CsrProcess) -{ - PCSR_SERVER_DLL ServerDll; - ULONG i; - ASSERT(ProcessStructureListLocked()); - - /* Remove us from the Process List */ - RemoveEntryList(&CsrProcess->ListLink); - - /* Release the lock */ - CsrReleaseProcessLock(); - - /* Loop every Server DLL */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Get the Server DLL */ - ServerDll = CsrLoadedServerDll[i]; - - /* Check if it's valid and if it has a Disconnect Callback */ - if ((ServerDll) && (ServerDll->DisconnectCallback)) - { - /* Call it */ - ServerDll->DisconnectCallback(CsrProcess); - } - } -} - -/*++ - * @name CsrInsertProcess - * - * The CsrInsertProcess routine inserts a CSR Process into the Process List - * and notifies Server DLLs of the creation of a new CSR Process. - * - * @param Parent - * Optional pointer to the CSR Process creating this CSR Process. - * - * @param CurrentProcess - * Optional pointer to the current CSR Process. - * - * @param CsrProcess - * Pointer to the CSR Process which is to be inserted. - * - * @return None. - * - * @remarks None. - * - *--*/ -VOID -NTAPI -CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL, - IN PCSR_PROCESS CurrentProcess OPTIONAL, - IN PCSR_PROCESS CsrProcess) -{ -#if 0 - PCSR_SERVER_DLL ServerDll; - ULONG i; -#endif - ASSERT(ProcessStructureListLocked()); - - /* Set the parent */ - CsrProcess->Parent = Parent; - - /* Insert it into the Root List */ - InsertTailList(&CsrRootProcess->ListLink, &CsrProcess->ListLink); -#if 0 - /* Notify the Server DLLs */ - for (i = 0; i < CSR_SERVER_DLL_MAX; i++) - { - /* Get the current Server DLL */ - ServerDll = CsrLoadedServerDll[i]; - - /* Make sure it's valid and that it has callback */ - if ((ServerDll) && (ServerDll->NewProcessCallback)) - { - ServerDll->NewProcessCallback(CurrentProcess, CsrProcess); - } - } -#endif -} - /*++ * @name CsrLockProcessByClientId * @implemented NT4 @@ -1237,4 +1176,308 @@ CsrLockProcessByClientId(IN HANDLE Pid, return Status; } +/*++ + * @name CsrShutdownProcesses + * @implemented NT4 + * + * The CsrShutdownProcesses routine shuts down every CSR Process possible + * and calls each Server DLL's shutdown notification. + * + * @param CallerLuid + * Pointer to the LUID of the CSR Process that is ordering the + * shutdown. + * + * @param Flags + * Flags to send to the shutdown notification routine. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * otherwise. + * + * @remarks None. + * + *--*/ +NTSTATUS +NTAPI +CsrShutdownProcesses(IN PLUID CallerLuid, + IN ULONG Flags) +{ + PLIST_ENTRY NextEntry; + PCSR_PROCESS CsrProcess; + NTSTATUS Status; + BOOLEAN FirstTry; + ULONG i; + PCSR_SERVER_DLL ServerDll; + ULONG Result = 0; /* Intentionally invalid enumeratee to silence compiler warning */ + + /* Acquire process lock */ + CsrAcquireProcessLock(); + + /* Add shutdown flag */ + CsrRootProcess->ShutdownFlags |= CsrShutdownSystem; + + /* Get the list pointers */ + NextEntry = CsrRootProcess->ListLink.Flink; + while (NextEntry != &CsrRootProcess->ListLink) + { + /* Get the Process */ + CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); + + /* Remove the skip flag, set shutdown flags to 0*/ + CsrProcess->Flags &= ~CsrProcessSkipShutdown; + CsrProcess->ShutdownFlags = 0; + + /* Move to the next */ + NextEntry = NextEntry->Flink; + } + + /* Set shudown Priority */ + CsrpSetToShutdownPriority(); + + /* Start looping */ + while (TRUE) + { + /* Find the next process to shutdown */ + CsrProcess = FindProcessForShutdown(CallerLuid); + if (!CsrProcess) break; + + /* Increase reference to process */ + CsrProcess->ReferenceCount++; + + FirstTry = TRUE; + while (TRUE) + { + /* Loop all the servers */ + for (i = 0; i < CSR_SERVER_DLL_MAX; i++) + { + /* Get the current server */ + ServerDll = CsrLoadedServerDll[i]; + if ((ServerDll) && (ServerDll->ShutdownProcessCallback)) + { + /* Release the lock, make the callback, and acquire it back */ + CsrReleaseProcessLock(); + Result = ServerDll->ShutdownProcessCallback(CsrProcess, + Flags, + FirstTry); + CsrAcquireProcessLock(); + + /* Check the result */ + if (Result == CsrShutdownCsrProcess) + { + /* The callback unlocked the process */ + break; + } + else if (Result == CsrShutdownCancelled) + { + /* Check if this was a forced shutdown */ + if (Flags & EWX_FORCE) + { + DPRINT1("Process %x cancelled forced shutdown (Dll = %d)\n", + CsrProcess->ClientId.UniqueProcess, i); + DbgBreakPoint(); + } + + /* Shutdown was cancelled, unlock and exit */ + CsrReleaseProcessLock(); + Status = STATUS_CANCELLED; + goto Quickie; + } + } + } + + /* No matches during the first try, so loop again */ + if ((FirstTry) && (Result == CsrShutdownNonCsrProcess)) + { + FirstTry = FALSE; + continue; + } + + /* Second try, break out */ + break; + } + + /* We've reached the final loop here, so dereference */ + if (i == CSR_SERVER_DLL_MAX) CsrLockedDereferenceProcess(CsrProcess); + } + + /* Success path */ + CsrReleaseProcessLock(); + Status = STATUS_SUCCESS; + +Quickie: + /* Return to normal priority */ + CsrpSetToNormalPriority(); + return Status; +} + +/* FIXME: Temporary hack. This is really "CsrShutdownProcess", mostly. Used by win32csr */ +NTSTATUS +WINAPI +CsrEnumProcesses(IN CSRSS_ENUM_PROCESS_PROC EnumProc, + IN PVOID Context) +{ + PVOID* RealContext = (PVOID*)Context; + PLUID CallerLuid = RealContext[0]; + PCSR_PROCESS CsrProcess = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + BOOLEAN FirstTry; + PLIST_ENTRY NextEntry; + ULONG Result = 0; + + /* Acquire process lock */ + CsrAcquireProcessLock(); + + /* Get the list pointers */ + NextEntry = CsrRootProcess->ListLink.Flink; + while (NextEntry != &CsrRootProcess->ListLink) + { + /* Get the Process */ + CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink); + + /* Remove the skip flag, set shutdown flags to 0*/ + CsrProcess->Flags &= ~CsrProcessSkipShutdown; + CsrProcess->ShutdownFlags = 0; + + /* Move to the next */ + NextEntry = NextEntry->Flink; + } + + /* Set shudown Priority */ + CsrSetToShutdownPriority(); + + /* Loop all processes */ + //DPRINT1("Enumerating for LUID: %lx %lx\n", CallerLuid->HighPart, CallerLuid->LowPart); + + /* Start looping */ + while (TRUE) + { + /* Find the next process to shutdown */ + FirstTry = TRUE; + if (!(CsrProcess = FindProcessForShutdown(CallerLuid))) + { + /* Done, quit */ + CsrReleaseProcessLock(); + Status = STATUS_SUCCESS; + goto Quickie; + } + +LoopAgain: + /* Release the lock, make the callback, and acquire it back */ + //DPRINT1("Found process: %lx\n", CsrProcess->ClientId.UniqueProcess); + CsrReleaseProcessLock(); + Result = (ULONG)EnumProc(CsrProcess, (PVOID)((ULONG_PTR)Context | FirstTry)); + CsrAcquireProcessLock(); + + /* Check the result */ + //DPRINT1("Result: %d\n", Result); + if (Result == CsrShutdownCsrProcess) + { + /* 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 */ + CsrReleaseProcessLock(); + Status = STATUS_CANCELLED; + goto Quickie; + } + + /* No matches during the first try, so loop again */ + if (FirstTry && Result == CsrShutdownNonCsrProcess) + { + FirstTry = FALSE; + goto LoopAgain; + } + } + +Quickie: + /* Return to normal priority */ + CsrSetToNormalPriority(); + return Status; +} + +/*++ + * @name CsrDebugProcess + * @implemented NT4 + * + * The CsrDebugProcess routine is deprecated in NT 5.1 and higher. It is + * exported only for compatibility with older CSR Server DLLs. + * + * @param CsrProcess + * Deprecated. + * + * @return Deprecated + * + * @remarks Deprecated. + * + *--*/ +NTSTATUS +NTAPI +CsrDebugProcess(IN PCSR_PROCESS CsrProcess) +{ + /* CSR does not handle debugging anymore */ + DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess); + return STATUS_UNSUCCESSFUL; +} + +/*++ + * @name CsrDebugProcessStop + * @implemented NT4 + * + * The CsrDebugProcessStop routine is deprecated in NT 5.1 and higher. It is + * exported only for compatibility with older CSR Server DLLs. + * + * @param CsrProcess + * Deprecated. + * + * @return Deprecated + * + * @remarks Deprecated. + * + *--*/ +NTSTATUS +NTAPI +CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess) +{ + /* CSR does not handle debugging anymore */ + DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess); + return STATUS_UNSUCCESSFUL; +} + +/*++ + * @name CsrSetForegroundPriority + * @implemented NT4 + * + * The CsrSetForegroundPriority routine sets the priority for the given CSR + * Process as a Foreground priority. + * + * @param CsrProcess + * Pointer to the CSR Process whose priority will be modified. + * + * @return None. + * + * @remarks None. + * + *--*/ +VOID +NTAPI +CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess) +{ + PROCESS_PRIORITY_CLASS PriorityClass; + + /* Set the Foreground bit on */ + PriorityClass.Foreground = TRUE; + + /* Set the new Priority */ + NtSetInformationProcess(CsrProcess->ProcessHandle, + ProcessPriorityClass, + &PriorityClass, + sizeof(PriorityClass)); +} + /* EOF */ diff --git a/subsystems/win32/csrss/csrsrv/session.c b/subsystems/win32/csrss/csrsrv/session.c index 361b3c3b9f2..66d273f845b 100644 --- a/subsystems/win32/csrss/csrsrv/session.c +++ b/subsystems/win32/csrss/csrsrv/session.c @@ -1,6 +1,6 @@ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System + * PROJECT: ReactOS CSR SubSystem * FILE: subsystems/win32/csrss/csrsrv/session.c * PURPOSE: CSR Server DLL Session Implementation * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) @@ -18,6 +18,16 @@ RTL_CRITICAL_SECTION CsrNtSessionLock; LIST_ENTRY CsrNtSessionList; +// Does it exist a enumeration associated with it ? +PSB_API_ROUTINE CsrServerSbApiDispatch[5] = +{ + CsrSbCreateSession, + CsrSbTerminateSession, + CsrSbForeignSessionComplete, + CsrSbCreateProcess, + NULL +}; + PCHAR CsrServerSbApiName[5] = { "SbCreateSession", @@ -208,8 +218,8 @@ CsrSbCreateSession(IN PSB_API_MSG ApiMessage) NTSTATUS Status; KERNEL_USER_TIMES KernelTimes; PCSR_THREAD CsrThread; - //PVOID ProcessData; - //ULONG i; + PVOID ProcessData; + ULONG i; /* Save the Process and Thread Handles */ hProcess = CreateSession->ProcessInfo.ProcessHandle; @@ -292,7 +302,7 @@ CsrSbCreateSession(IN PSB_API_MSG ApiMessage) /* Set the Process Priority */ CsrSetBackgroundPriority(CsrProcess); -#if 0 + /* Get the first data location */ ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX]; @@ -315,10 +325,10 @@ CsrSbCreateSession(IN PSB_API_MSG ApiMessage) CsrProcess->ServerData[i] = NULL; } } -#else - /* HACKZ: should go in BaseSrv part of CreateCallback done in Insert below */ - RtlInitializeCriticalSection(&CsrProcess->HandleTableLock); -#endif + + /* HACK: FIXME: should go in BaseSrv part of CreateCallback done in Insert below */ + // RtlInitializeCriticalSection(&CsrProcess->HandleTableLock); + /* Insert the Process */ CsrInsertProcess(NULL, NULL, CsrProcess); @@ -397,15 +407,6 @@ CsrSbCreateProcess(IN PSB_API_MSG ApiMessage) return TRUE; } -PSB_API_ROUTINE CsrServerSbApiDispatch[5] = -{ - CsrSbCreateSession, - CsrSbTerminateSession, - CsrSbForeignSessionComplete, - CsrSbCreateProcess, - NULL -}; - /*++ * @name CsrSbApiHandleConnectionRequest * diff --git a/subsystems/win32/csrss/csrsrv/thredsup.c b/subsystems/win32/csrss/csrsrv/thredsup.c index d1c3de4b2ab..72566f8efc1 100644 --- a/subsystems/win32/csrss/csrsrv/thredsup.c +++ b/subsystems/win32/csrss/csrsrv/thredsup.c @@ -1,10 +1,10 @@ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CSR Sub System + * PROJECT: ReactOS CSR SubSystem * FILE: subsystems/win32/csrss/csrsrv/thredsup.c - * PURPOSE: CSR Server DLL Thread Implementation + * PURPOSE: CSR Server DLL Thread Management * PROGRAMMERS: ReactOS Portable Systems Group - * Alex Ionescu + * Alex Ionescu (alex@relsoft.net) */ /* INCLUDES *******************************************************************/ @@ -21,7 +21,8 @@ LIST_ENTRY CsrThreadHashTable[256]; -/* FUNCTIONS ******************************************************************/ + +/* PRIVATE FUNCTIONS **********************************************************/ /*++ * @name ProtectHandle @@ -201,6 +202,7 @@ CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); /* Compare the CID */ + // FIXME: if (*(PULONGLONG)&FoundThread->ClientId == *(PULONGLONG)ClientId) if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread) { /* Match found, return the process */ @@ -389,6 +391,87 @@ CsrRemoveThread(IN PCSR_THREAD CsrThread) CsrThread->Flags |= CsrThreadInTermination; } +/*++ + * @name CsrThreadRefcountZero + * + * The CsrThreadRefcountZero routine is executed when a CSR Thread has lost + * all its active references. It removes and de-allocates the CSR Thread. + * + * @param CsrThread + * Pointer to the CSR Thread that is to be deleted. + * + * @return None. + * + * @remarks Do not call this routine. It is reserved for the internal + * thread management routines when a CSR Thread has lost all + * its references. + * + * This routine is called with the Process Lock held. + * + *--*/ +VOID +NTAPI +CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) +{ + PCSR_PROCESS CsrProcess = CsrThread->Process; + NTSTATUS Status; + ASSERT(ProcessStructureListLocked()); + + /* Remove this thread */ + CsrRemoveThread(CsrThread); + + /* Release the Process Lock */ + CsrReleaseProcessLock(); + + /* Close the NT Thread Handle */ + if (CsrThread->ThreadHandle) + { + UnProtectHandle(CsrThread->ThreadHandle); + Status = NtClose(CsrThread->ThreadHandle); + ASSERT(NT_SUCCESS(Status)); + } + + /* De-allocate the CSR Thread Object */ + CsrDeallocateThread(CsrThread); + + /* Remove a reference from the process */ + CsrDereferenceProcess(CsrProcess); +} + +/*++ + * @name CsrLockedDereferenceThread + * + * The CsrLockedDereferenceThread dereferences a CSR Thread while the + * Process Lock is already being held. + * + * @param CsrThread + * Pointer to the CSR Thread to be dereferenced. + * + * @return None. + * + * @remarks This routine will return with the Process Lock held. + * + *--*/ +VOID +NTAPI +CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread) +{ + LONG LockCount; + + /* Decrease reference count */ + LockCount = --CsrThread->ReferenceCount; + ASSERT(LockCount >= 0); + if (!LockCount) + { + /* Call the generic cleanup code */ + CsrThreadRefcountZero(CsrThread); + CsrAcquireProcessLock(); + } +} + + +/* PUBLIC FUNCTIONS ***********************************************************/ + /*++ * @name CsrCreateRemoteThread * @implemented NT4 @@ -490,53 +573,6 @@ CsrCreateRemoteThread(IN HANDLE hThread, return STATUS_SUCCESS; } -/*++ - * @name CsrThreadRefcountZero - * - * The CsrThreadRefcountZero routine is executed when a CSR Thread has lost - * all its active references. It removes and de-allocates the CSR Thread. - * - * @param CsrThread - * Pointer to the CSR Thread that is to be deleted. - * - * @return None. - * - * @remarks Do not call this routine. It is reserved for the internal - * thread management routines when a CSR Thread has lost all - * its references. - * - * This routine is called with the Process Lock held. - * - *--*/ -VOID -NTAPI -CsrThreadRefcountZero(IN PCSR_THREAD CsrThread) -{ - PCSR_PROCESS CsrProcess = CsrThread->Process; - NTSTATUS Status; - ASSERT(ProcessStructureListLocked()); - - /* Remove this thread */ - CsrRemoveThread(CsrThread); - - /* Release the Process Lock */ - CsrReleaseProcessLock(); - - /* Close the NT Thread Handle */ - if (CsrThread->ThreadHandle) - { - UnProtectHandle(CsrThread->ThreadHandle); - Status = NtClose(CsrThread->ThreadHandle); - ASSERT(NT_SUCCESS(Status)); - } - - /* De-allocate the CSR Thread Object */ - CsrDeallocateThread(CsrThread); - - /* Remove a reference from the process */ - CsrDereferenceProcess(CsrProcess); -} - /*++ * @name CsrDestroyThread * @implemented NT4 @@ -606,37 +642,6 @@ CsrDestroyThread(IN PCLIENT_ID Cid) return STATUS_SUCCESS; } -/*++ - * @name CsrLockedDereferenceThread - * - * The CsrLockedDereferenceThread dereferences a CSR Thread while the - * Process Lock is already being held. - * - * @param CsrThread - * Pointer to the CSR Thread to be dereferenced. - * - * @return None. - * - * @remarks This routine will return with the Process Lock held. - * - *--*/ -VOID -NTAPI -CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread) -{ - LONG LockCount; - - /* Decrease reference count */ - LockCount = --CsrThread->ReferenceCount; - ASSERT(LockCount >= 0); - if (!LockCount) - { - /* Call the generic cleanup code */ - CsrThreadRefcountZero(CsrThread); - CsrAcquireProcessLock(); - } -} - /*++ * @name CsrCreateThread * @implemented NT4 @@ -662,6 +667,79 @@ CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread) *--*/ NTSTATUS NTAPI +#if 0 +CsrCreateThread(IN PCSR_PROCESS CsrProcess, + IN HANDLE hThread, + IN PCLIENT_ID ClientId, + IN BOOLEAN HaveClient) +{ + NTSTATUS Status; + PCSR_THREAD CsrThread, CurrentThread; + PCSR_PROCESS CurrentProcess; + CLIENT_ID CurrentCid; + KERNEL_USER_TIMES KernelTimes; + DPRINT("CSRSRV: %s called\n", __FUNCTION__); + + if (HaveClient) + { + /* Get the current thread and CID */ + CurrentThread = NtCurrentTeb()->CsrClientThread; + CurrentCid = CurrentThread->ClientId; + + /* Acquire the Process Lock */ + CsrAcquireProcessLock(); + + /* Get the current Process and make sure the Thread is valid with this CID */ + CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid); + if (!CurrentThread) + { + DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__); + CsrReleaseProcessLock(); + return STATUS_THREAD_IS_TERMINATING; + } + } + else + { + /* Acquire the Process Lock */ + CsrAcquireProcessLock(); + } + + /* Get the Thread Create Time */ + Status = NtQueryInformationThread(hThread, + ThreadTimes, + (PVOID)&KernelTimes, + sizeof(KernelTimes), + NULL); + if (!NT_SUCCESS(Status)) + { + CsrReleaseProcessLock(); + return Status; + } + + /* Allocate a CSR Thread Structure */ + CsrThread = CsrAllocateThread(CsrProcess); + if (!CsrThread) + { + DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__); + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } + + /* Save the data we have */ + CsrThread->CreateTime = KernelTimes.CreateTime; + CsrThread->ClientId = *ClientId; + CsrThread->ThreadHandle = hThread; + ProtectHandle(hThread); + CsrThread->Flags = 0; + + /* Insert the Thread into the Process */ + CsrInsertThread(CsrProcess, CsrThread); + + /* Release the lock and return */ + CsrReleaseProcessLock(); + return STATUS_SUCCESS; +} +#else CsrCreateThread(IN PCSR_PROCESS CsrProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId) @@ -718,6 +796,7 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess, CsrReleaseProcessLock(); return STATUS_SUCCESS; } +#endif /*++ * @name CsrAddStaticServerThread @@ -816,4 +895,229 @@ CsrDereferenceThread(IN PCSR_THREAD CsrThread) } } + +/*++ + * @name CsrExecServerThread + * @implemented NT4 + * + * The CsrExecServerThread routine creates an NT Thread and then + * initializes a CSR Thread for it. + * + * @param ThreadHandler + * Pointer to the thread's startup routine. + * + * @param Flags + * Initial CSR Thread Flags to set to the CSR Thread. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * otherwise. + * + * @remarks This routine is similar to CsrAddStaticServerThread, but it + * also creates an NT Thread instead of expecting one to already + * exist. + * + *--*/ +NTSTATUS +NTAPI +CsrExecServerThread(IN PVOID ThreadHandler, + IN ULONG Flags) +{ + PCSR_THREAD CsrThread; + HANDLE hThread; + CLIENT_ID ClientId; + NTSTATUS Status; + + /* Acquire process lock */ + CsrAcquireProcessLock(); + + /* Allocate a CSR Thread in the Root Process */ + ASSERT(CsrRootProcess != NULL); + CsrThread = CsrAllocateThread(CsrRootProcess); + if (!CsrThread) + { + /* Fail */ + CsrReleaseProcessLock(); + return STATUS_NO_MEMORY; + } + + /* Create the Thread */ + Status = RtlCreateUserThread(NtCurrentProcess(), + NULL, + FALSE, + 0, + 0, + 0, + ThreadHandler, + NULL, + &hThread, + &ClientId); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + CsrDeallocateThread(CsrThread); + CsrReleaseProcessLock(); + return Status; + } + + /* Setup the Thread Object */ + CsrThread->ThreadHandle = hThread; + ProtectHandle(hThread); + CsrThread->ClientId = ClientId; + CsrThread->Flags = Flags; + + /* Insert it into the Thread List */ + InsertHeadList(&CsrRootProcess->ThreadList, &CsrThread->Link); + + /* Increase the thread count */ + CsrRootProcess->ThreadCount++; + + /* Return */ + CsrReleaseProcessLock(); + return Status; +} + +/*++ + * @name CsrLockThreadByClientId + * @implemented NT4 + * + * The CsrLockThreadByClientId routine locks the CSR Thread corresponding + * to the given Thread ID and optionally returns it. + * + * @param Tid + * Thread ID corresponding to the CSR Thread which will be locked. + * + * @param CsrThread + * Optional pointer to a CSR Thread pointer which will hold the + * CSR Thread corresponding to the given Thread ID. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * otherwise. + * + * @remarks Locking a CSR Thread is defined as acquiring an extra + * reference to it and returning with the Process Lock held. + * + *--*/ +NTSTATUS +NTAPI +CsrLockThreadByClientId(IN HANDLE Tid, + OUT PCSR_THREAD *CsrThread) +{ + PLIST_ENTRY NextEntry; + PCSR_THREAD CurrentThread = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + ULONG i; + + /* Acquire the lock */ + CsrAcquireProcessLock(); + + /* Assume failure */ + ASSERT(CsrThread != NULL); + *CsrThread = NULL; + + /* Convert to Hash */ + i = CsrHashThread(Tid); + + /* Setup the List Pointers */ + NextEntry = CsrThreadHashTable[i].Flink; + + /* Start Loop */ + while (NextEntry != &CsrThreadHashTable[i]) + { + /* Get the Process */ + CurrentThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); + + /* Check for PID Match */ + if ((CurrentThread->ClientId.UniqueThread == Tid) && + !(CurrentThread->Flags & CsrThreadTerminated)) + { + /* Get out of here */ + break; + } + + /* Next entry */ + NextEntry = NextEntry->Flink; + } + + /* Nothing found if we got back to the list */ + if (NextEntry == &CsrThreadHashTable[i]) CurrentThread = NULL; + + /* Did the loop find something? */ + if (CurrentThread) + { + /* Reference the found thread */ + Status = STATUS_SUCCESS; + CurrentThread->ReferenceCount++; + *CsrThread = CurrentThread; + } + else + { + /* Nothing found, release the lock */ + Status = STATUS_UNSUCCESSFUL; + CsrReleaseProcessLock(); + } + + /* Return the status */ + return Status; +} + +/*++ + * @name CsrReferenceThread + * @implemented NT4 + * + * The CsrReferenceThread routine increases the active reference count of + * a CSR Thread. + * + * @param CsrThread + * Pointer to the CSR Thread whose reference count will be increased. + * + * @return None. + * + * @remarks Do not use this routine if the Process Lock is already held. + * + *--*/ +VOID +NTAPI +CsrReferenceThread(IN PCSR_THREAD CsrThread) +{ + /* Acquire process lock */ + CsrAcquireProcessLock(); + + /* Sanity checks */ + ASSERT(CsrThread->Flags & CsrThreadTerminated); // CSR_THREAD_DESTROYED in ASSERT + ASSERT(CsrThread->ReferenceCount != 0); + + /* Increment reference count */ + CsrThread->ReferenceCount++; + + /* Release the lock */ + CsrReleaseProcessLock(); +} + +/*++ + * @name CsrUnlockThread + * @implemented NT4 + * + * The CsrUnlockThread undoes a previous CsrLockThreadByClientId operation. + * + * @param CsrThread + * Pointer to a previously locked CSR Thread. + * + * @return STATUS_SUCCESS. + * + * @remarks This routine must be called with the Process Lock held. + * + *--*/ +NTSTATUS +NTAPI +CsrUnlockThread(IN PCSR_THREAD CsrThread) +{ + /* Dereference the Thread */ + ASSERT(ProcessStructureListLocked()); + CsrLockedDereferenceThread(CsrThread); + + /* Release the lock and return */ + CsrReleaseProcessLock(); + return STATUS_SUCCESS; +} + /* EOF */ diff --git a/subsystems/win32/csrss/csrss.c b/subsystems/win32/csrss/csrss.c index 4ea1ee7047a..110b95ccfba 100644 --- a/subsystems/win32/csrss/csrss.c +++ b/subsystems/win32/csrss/csrss.c @@ -2,8 +2,8 @@ * PROJECT: ReactOS Client Server Runtime SubSystem (CSRSS) * LICENSE: BSD - See COPYING.ARM in root directory * FILE: subsystems/win32/csrss/csrss.c - * PURPOSE: Main Executable Code - * PROGRAMMERS: Alex Ionescu + * PURPOSE: CSRSS Main Executable Code + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) * ReactOS Portable Systems Group */ @@ -14,6 +14,8 @@ #define NTOS_MODE_USER #include #include +// #include + #define NDEBUG #include @@ -41,7 +43,7 @@ _main(int argc, { KPRIORITY BasePriority = (8 + 1) + 4; NTSTATUS Status; - //ULONG Response; + //ULONG Response; // see the #if 0 UNREFERENCED_PARAMETER(envp); UNREFERENCED_PARAMETER(DebugFlag); @@ -83,7 +85,7 @@ _main(int argc, CsrpSetDefaultProcessHardErrorMode(); /* If this is Session 0, make sure killing us bugchecks the system */ - if (!NtCurrentPeb()->SessionId) RtlSetProcessIsCritical(TRUE, NULL, FALSE); + if (NtCurrentPeb()->SessionId == 0) RtlSetProcessIsCritical(TRUE, NULL, FALSE); /* Kill this thread. CSRSRV keeps us going */ NtTerminateThread(NtCurrentThread(), Status); diff --git a/subsystems/win32/csrss/include/api.h b/subsystems/win32/csrss/include/api.h index c7ee19ce5d9..1466370513d 100644 --- a/subsystems/win32/csrss/include/api.h +++ b/subsystems/win32/csrss/include/api.h @@ -15,13 +15,13 @@ #define CsrAcquireProcessLock() \ - RtlEnterCriticalSection(&ProcessDataLock); // CsrProcessLock + RtlEnterCriticalSection(&CsrProcessLock); #define CsrReleaseProcessLock() \ - RtlLeaveCriticalSection(&ProcessDataLock); + RtlLeaveCriticalSection(&CsrProcessLock); #define ProcessStructureListLocked() \ - (ProcessDataLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread) + (CsrProcessLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread) #define CsrAcquireWaitLock() \ RtlEnterCriticalSection(&CsrWaitListsLock); @@ -119,7 +119,7 @@ extern HANDLE CsrSmApiPort; extern HANDLE CsrSbApiPort; extern LIST_ENTRY CsrThreadHashTable[256]; extern PCSR_PROCESS CsrRootProcess; -extern RTL_CRITICAL_SECTION ProcessDataLock, CsrWaitListsLock; +extern RTL_CRITICAL_SECTION CsrProcessLock, CsrWaitListsLock; extern UNICODE_STRING CsrDirectoryName; extern ULONG CsrDebug; extern ULONG CsrTotalPerProcessDataLength;