Author: ion Date: Wed Feb 15 16:11:12 2012 New Revision: 55610
URL: http://svn.reactos.org/svn/reactos?rev=55610&view=rev Log: [CSRSRV]: Merge some initialization code from CSRSRV, including CsrParseServerCommandLine and CsrCreateSessionObjectDirectory. CsrSrvCreateSharedSection is now called correctly based on registry/command-line settings. Remove legacy functions that are no longer needed as a result. [CSRSRV]: Flatten out the initialization code instead of a table of initialization functions. [CSRSRV]: Make BasepFakeStaticServerData (our fake BaseSrv.DLL that's static inside CSRSRV for now) also create the BaseNamedObject Directory, along with the right ACLs and symbolic links, as well as the \Restricted sub-directory. Remove legacy function that was doing this before.
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c trunk/reactos/subsystems/win32/csrss/csrsrv/init.c trunk/reactos/subsystems/win32/csrss/csrsrv/procsup.c trunk/reactos/subsystems/win32/csrss/csrsrv/srv.h trunk/reactos/subsystems/win32/csrss/csrss.c
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csrs... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] Wed Feb 15 16:11:12 2012 @@ -149,14 +149,14 @@ ULONG ViewSize = 0; SYSTEM_BASIC_INFORMATION CsrNtSysInfo; PPEB Peb = NtCurrentPeb(); - + /* ReactOS Hackssss */ Status = NtQuerySystemInformation(SystemBasicInformation, &CsrNtSysInfo, sizeof(SYSTEM_BASIC_INFORMATION), NULL); ASSERT(NT_SUCCESS(Status)); - + /* Find the first comma, and null terminate */ while (*SizeValue) { @@ -170,18 +170,18 @@ SizeValue++; } } - + /* Make sure it's valid */ if (!*SizeValue) return STATUS_INVALID_PARAMETER; - + /* Convert it to an integer */ Status = RtlCharToInteger(SizeValue, 0, &Size); if (!NT_SUCCESS(Status)) return Status; - + /* Multiply by 1024 entries and round to page size */ CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize); DPRINT1("Size: %lx\n", CsrSrvSharedSectionSize); - + /* Create the Secion */ SectionSize.LowPart = CsrSrvSharedSectionSize; SectionSize.HighPart = 0; @@ -193,7 +193,7 @@ SEC_BASED | SEC_RESERVE, NULL); if (!NT_SUCCESS(Status)) return Status; - + /* Map the section */ Status = NtMapViewOfSection(CsrSrvSharedSection, NtCurrentProcess(), @@ -211,12 +211,12 @@ NtClose(CsrSrvSharedSection); return(Status); } - + /* FIXME: Write the value to registry */ - + /* The Heap is the same place as the Base */ CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase; - + /* Create the heap */ if (!(RtlCreateHeap(HEAP_ZERO_MEMORY, CsrSrvSharedSectionHeap, @@ -231,18 +231,18 @@ NtClose(CsrSrvSharedSection); return STATUS_NO_MEMORY; } - + /* Now allocate space from the heap for the Shared Data */ CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap, 0, 4 * // HAX CSR_SERVER_DLL_MAX * sizeof(PVOID)); - + /* Write the values to the PEB */ Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase; Peb->ReadOnlySharedMemoryHeap = CsrSrvSharedSectionHeap; Peb->ReadOnlyStaticServerData = CsrSrvSharedStaticServerData; - + /* Return */ return STATUS_SUCCESS; } @@ -274,7 +274,7 @@ { NTSTATUS Status; ULONG ViewSize = 0; - + /* Check if we have a process */ if (CsrProcess) { @@ -298,17 +298,132 @@ } if (!NT_SUCCESS(Status)) return Status; } - + /* Write the values in the Connection Info structure */ ConnectInfo->SharedSectionBase = CsrSrvSharedSectionBase; ConnectInfo->SharedSectionHeap = CsrSrvSharedSectionHeap; ConnectInfo->SharedSectionData = CsrSrvSharedStaticServerData; - + /* Return success */ return STATUS_SUCCESS; }
PBASE_STATIC_SERVER_DATA BaseStaticServerData; + +NTSTATUS +NTAPI +CreateBaseAcls(OUT PACL* Dacl, + OUT PACL* RestrictedDacl) +{ + PSID SystemSid, WorldSid, RestrictedSid; + SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; + NTSTATUS Status; + UCHAR KeyValueBuffer[0x40]; + PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo; + UNICODE_STRING KeyName; + ULONG ProtectionMode = 0; + ULONG AclLength, ResultLength; + HANDLE hKey; + OBJECT_ATTRIBUTES ObjectAttributes; + + /* Open the Session Manager Key */ + RtlInitUnicodeString(&KeyName, SM_REG_KEY); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + /* Read the key value */ + RtlInitUnicodeString(&KeyName, L"ProtectionMode"); + Status = NtQueryValueKey(hKey, + &KeyName, + KeyValuePartialInformation, + KeyValueBuffer, + sizeof(KeyValueBuffer), + &ResultLength); + + /* Make sure it's what we expect it to be */ + KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer; + if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) && + (*(PULONG)KeyValuePartialInfo->Data)) + { + /* Save the Protection Mode */ + ProtectionMode = *(PULONG)KeyValuePartialInfo->Data; + } + + /* Close the handle */ + NtClose(hKey); + } + + /* Allocate the System SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, + &SystemSid); + ASSERT(NT_SUCCESS(Status)); + + /* Allocate the World SID */ + Status = RtlAllocateAndInitializeSid(&WorldAuthority, + 1, SECURITY_WORLD_RID, + 0, 0, 0, 0, 0, 0, 0, + &WorldSid); + ASSERT(NT_SUCCESS(Status)); + + /* Allocate the restricted SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, SECURITY_RESTRICTED_CODE_RID, + 0, 0, 0, 0, 0, 0, 0, + &RestrictedSid); + ASSERT(NT_SUCCESS(Status)); + + /* Allocate one ACL with 3 ACEs each for one SID */ + AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + + RtlLengthSid(SystemSid) + + RtlLengthSid(RestrictedSid) + + RtlLengthSid(WorldSid); + *Dacl = RtlAllocateHeap(CsrHeap, 0, AclLength); + ASSERT(*Dacl != NULL); + + /* Set the correct header fields */ + Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2); + ASSERT(NT_SUCCESS(Status)); + + /* Give the appropriate rights to each SID */ + /* FIXME: Should check SessionId/ProtectionMode */ + Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid); + ASSERT(NT_SUCCESS(Status)); + + /* Now allocate the restricted DACL */ + *RestrictedDacl = RtlAllocateHeap(CsrHeap, 0, AclLength); + ASSERT(*RestrictedDacl != NULL); + + /* Initialize it */ + Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2); + ASSERT(NT_SUCCESS(Status)); + + /* And add the same ACEs as before */ + /* FIXME: Not really fully correct */ + Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid); + ASSERT(NT_SUCCESS(Status)); + + /* The SIDs are captured, can free them now */ + RtlFreeHeap(CsrHeap, 0, SystemSid); + RtlFreeHeap(CsrHeap, 0, WorldSid); + RtlFreeHeap(CsrHeap, 0, RestrictedSid); + return Status; +}
VOID WINAPI @@ -323,6 +438,15 @@ 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; + BOOLEAN LuidEnabled; RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] = { { @@ -334,37 +458,39 @@ {0} };
+ /* Get the session ID */ + SessionId = NtCurrentPeb()->SessionId; + /* Get the Windows directory */ RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer)); Status = RtlExpandEnvironmentStrings_U(NULL, &UnexpandedSystemRootString, &SystemRootString, NULL); - DPRINT1("Status: %lx. Root: %wZ\n", Status, &SystemRootString); - ASSERT(NT_SUCCESS(Status)); - + 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; @@ -373,7 +499,7 @@ sizeof(BaseStaticServerData->TimeOfDay), NULL); ASSERT(NT_SUCCESS(Status)); - + /* Make a shared heap copy of the Windows directory */ BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory; HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap, @@ -384,7 +510,7 @@ BaseStaticServerData->WindowsDirectory.Buffer, BaseSrvWindowsDirectory.MaximumLength); BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer; - + /* Make a shared heap copy of the System directory */ BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory; HeapBuffer = RtlAllocateHeap(CsrSrvSharedSectionHeap, @@ -395,12 +521,12 @@ 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 + @@ -413,7 +539,7 @@ 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 @@ -424,7 +550,7 @@ */ 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, @@ -444,21 +570,121 @@ /* 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; - BaseStaticServerData->LUIDDeviceMapsEnabled = FALSE; - - /* FIXME: Symlinks */ + + /* 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 */ + NtQueryInformationProcess(NtCurrentProcess(), + ProcessLUIDDeviceMapsEnabled, + &LuidEnabled, + sizeof(LuidEnabled), + NULL); + 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"); + RtlInitUnicodeString(&SymlinkName, Buffer); + 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; } @@ -480,11 +706,11 @@ DPRINT("CSR: %s: Handling: %p\n", __FUNCTION__, Request);
ConnectInfo = (PCSR_CONNECTION_INFO)(Request + 1); - + /* Save the process ID */ RtlZeroMemory(ConnectInfo, sizeof(CSR_CONNECTION_INFO)); ConnectInfo->ProcessId = NtCurrentTeb()->ClientId.UniqueProcess; - + ProcessData = CsrGetProcessData(Request->ClientId.UniqueProcess); if (ProcessData == NULL) { @@ -495,11 +721,11 @@ Request->ClientId.UniqueProcess); } } - + if (ProcessData->Process == NULL) { OBJECT_ATTRIBUTES ObjectAttributes; - + InitializeObjectAttributes(&ObjectAttributes, NULL, 0, @@ -513,7 +739,7 @@ &Request->ClientId); DPRINT1("Status: %lx. Handle: %lx\n", Status, ProcessData->Process); } - + if (ProcessData) { /* Attach the Shared Section */ @@ -528,7 +754,7 @@ DPRINT1("Shared section map failed: %lx\n", Status); } } - + Status = NtAcceptConnectPort(&ServerPort, NULL, Request, @@ -567,9 +793,9 @@ DPRINT1("CSR: Unable to create server thread\n"); return Status; } - + CsrAddStaticServerThread(ServerThread, &ClientId, 0); - + NtResumeThread(ServerThread, NULL);
NtClose(ServerThread); @@ -638,7 +864,7 @@ PCSR_THREAD ServerThread;
DPRINT("CSR: %s called\n", __FUNCTION__); - + /* Connect to user32 */ while (!CsrConnectToUser()) { @@ -732,11 +958,11 @@ { PCSR_THREAD Thread; PCSRSS_PROCESS_DATA Process = NULL; - + //DPRINT1("locate thread %lx/%lx\n", Request->Header.ClientId.UniqueProcess, Request->Header.ClientId.UniqueThread); Thread = CsrLocateThreadByClientId(&Process, &Request->Header.ClientId); //DPRINT1("Thread found: %p %p\n", Thread, Process); - + /* Call the Handler */ if (Thread) NtCurrentTeb()->CsrClientThread = Thread; CsrApiCallHandler(ProcessData, Request); @@ -835,7 +1061,7 @@ DPRINT1("CSR: SMSS died\n"); Reply = NULL; break; - + default: DPRINT1("CSR: %s received message (type=%d)\n", __FUNCTION__, Request.h.u2.s2.Type);
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/init.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csrs... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/csrsrv/init.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/csrsrv/init.c [iso-8859-1] Wed Feb 15 16:11:12 2012 @@ -24,6 +24,13 @@ HANDLE hBootstrapOk = (HANDLE) 0; HANDLE hSmApiPort = (HANDLE) 0; HANDLE hApiPort = (HANDLE) 0; +ULONG CsrDebug = 0xFFFFFFFF; +ULONG CsrMaxApiRequestThreads; +ULONG CsrTotalPerProcessDataLength; +ULONG SessionId; +HANDLE BNOLinksDirectory; +HANDLE SessionObjectDirectory; +HANDLE DosDevicesDirectory;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -119,38 +126,6 @@ Status = (*ServerProcs[i].ProcessDeletedProc)(ProcessData);
return Status; -} - - -ULONG -InitializeVideoAddressSpace(VOID); - -/********************************************************************** - * CsrpCreateObjectDirectory/3 - */ -static NTSTATUS -CsrpCreateObjectDirectory (int argc, char ** argv, char ** envp) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES Attributes; - - DPRINT("CSR: %s called\n", __FUNCTION__); - - - /* create object directory ('\Windows') */ - RtlCreateUnicodeString (&CsrDirectoryName, - L"\Windows"); - - InitializeObjectAttributes (&Attributes, - &CsrDirectoryName, - OBJ_OPENIF, - NULL, - NULL); - - Status = NtOpenDirectoryObject(&CsrObjectDirectory, - DIRECTORY_ALL_ACCESS, - &Attributes); - return Status; }
/********************************************************************** @@ -166,7 +141,7 @@ * TODO: DWORD ServerId) */ static NTSTATUS -CsrpInitWin32Csr (int argc, char ** argv, char ** envp) +CsrpInitWin32Csr (VOID) { NTSTATUS Status; UNICODE_STRING DllName; @@ -271,74 +246,6 @@
/* === INIT ROUTINES === */
-/********************************************************************** - * CsrpCreateBNODirectory/3 - * - * These used to be part of kernel32 startup, but that clearly wasn't a good - * idea, as races were definately possible. These are moved (as in the - * previous fixmes). - */ -static NTSTATUS -CsrpCreateBNODirectory (int argc, char ** argv, char ** envp) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\BaseNamedObjects"); - UNICODE_STRING SymName = RTL_CONSTANT_STRING(L"Local"); - UNICODE_STRING SymName2 = RTL_CONSTANT_STRING(L"Global"); - HANDLE DirHandle, SymHandle; - - /* Seems like a good place to create these objects which are needed by - * win32 processes */ - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtCreateDirectoryObject(&DirHandle, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateDirectoryObject() failed %08x\n", Status); - } - - /* Create the "local" Symbolic Link. - * FIXME: CSR should do this -- Fixed */ - InitializeObjectAttributes(&ObjectAttributes, - &SymName, - OBJ_CASE_INSENSITIVE, - DirHandle, - NULL); - Status = NtCreateSymbolicLinkObject(&SymHandle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes, - &Name); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateDirectoryObject() failed %08x\n", Status); - } - - /* Create the "global" Symbolic Link. */ - InitializeObjectAttributes(&ObjectAttributes, - &SymName2, - OBJ_CASE_INSENSITIVE, - DirHandle, - NULL); - Status = NtCreateSymbolicLinkObject(&SymHandle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes, - &Name); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateDirectoryObject() failed %08x\n", Status); - } - - return Status; -} - - VOID WINAPI BasepFakeStaticServerData(VOID); @@ -351,12 +258,11 @@ * CsrpCreateHeap/3 */ static NTSTATUS -CsrpCreateHeap (int argc, char ** argv, char ** envp) -{ - CHAR Value[] = "1024,3072,512"; - NTSTATUS Status; +CsrpCreateHeap (VOID) +{ DPRINT("CSR: %s called\n", __FUNCTION__);
+ CsrHeap = RtlGetProcessHeap(); CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 65536, @@ -368,29 +274,7 @@ return STATUS_UNSUCCESSFUL; }
- - Status = CsrSrvCreateSharedSection(Value); - if (Status != STATUS_SUCCESS) - { - DPRINT1("CsrSrvCreateSharedSection failed with status 0x%08lx\n", Status); - ASSERT(FALSE); - } - - BasepFakeStaticServerData(); return STATUS_SUCCESS; -} - -/********************************************************************** - * CsrpCreateCallbackPort/3 - */ -static NTSTATUS -CsrpCreateCallbackPort (int argc, char ** argv, char ** envp) -{ - DPRINT("CSR: %s called\n", __FUNCTION__); - - return CsrpCreateListenPort (L"\Windows\SbApiPort", - & hSbApiPort, - ServerSbApiPortThread); }
/********************************************************************** @@ -398,7 +282,7 @@ */ BOOLEAN g_ModernSm; static NTSTATUS -CsrpRegisterSubsystem (int argc, char ** argv, char ** envp) +CsrpRegisterSubsystem (VOID) { NTSTATUS Status = STATUS_SUCCESS; OBJECT_ATTRIBUTES BootstrapOkAttributes; @@ -460,52 +344,559 @@ return Status; }
-/********************************************************************** - * CsrpCreateApiPort/2 - */ -static NTSTATUS -CsrpCreateApiPort (int argc, char ** argv, char ** envp) -{ - DPRINT("CSR: %s called\n", __FUNCTION__); - - CsrInitProcessData(); - - return CsrpCreateListenPort(L"\Windows\ApiPort", &hApiPort, - (PTHREAD_START_ROUTINE)ClientConnectionThread); -} - -/********************************************************************** - * CsrpApiRegisterDef/0 - */ -static NTSTATUS -CsrpApiRegisterDef (int argc, char ** argv, char ** envp) -{ - return CsrApiRegisterDefinitions(NativeDefinitions); -} - -static NTSTATUS -CsrpCreateHardErrorPort (int argc, char ** argv, char ** envp) -{ - return NtSetDefaultHardErrorPort(hApiPort); -} - -typedef NTSTATUS (* CSR_INIT_ROUTINE)(int,char**,char**); - -struct { - BOOL Required; - CSR_INIT_ROUTINE EntryPoint; - PCHAR ErrorMessage; -} InitRoutine [] = { - {TRUE, CsrpCreateBNODirectory, "create base named objects directory"}, - {TRUE, CsrpCreateHeap, "create the CSR heap"}, - {TRUE, CsrpCreateApiPort, "create the api port \Windows\ApiPort"}, - {TRUE, CsrpCreateHardErrorPort, "create the hard error port"}, - {TRUE, CsrpCreateObjectDirectory,"create the object directory \Windows"}, - {TRUE, CsrpApiRegisterDef, "initialize api definitions"}, - {TRUE, CsrpInitWin32Csr, "load usermode dll"}, - {TRUE, CsrpCreateCallbackPort, "create the callback port \Windows\SbApiPort"}, - {TRUE, CsrpRegisterSubsystem, "register with SM"}, -}; +/*++ + * @name CsrSetDirectorySecurity + * + * The CsrSetDirectorySecurity routine sets the security descriptor for the + * specified Object Directory. + * + * @param ObjectDirectory + * Handle fo the Object Directory to protect. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * othwerwise. + * + * @remarks None. + * + *--*/ +NTSTATUS +NTAPI +CsrSetDirectorySecurity(IN HANDLE ObjectDirectory) +{ + /* FIXME: Implement */ + return STATUS_SUCCESS; +} + +/*++ + * @name GetDosDevicesProtection + * + * The GetDosDevicesProtection creates a security descriptor for the DOS Devices + * Object Directory. + * + * @param DosDevicesSd + * Pointer to the Security Descriptor to return. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * othwerwise. + * + * @remarks Depending on the DOS Devices Protection Mode (set in the registry), + * regular users may or may not have full access to the directory. + * + *--*/ +NTSTATUS +NTAPI +GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd) +{ + SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY}; + PSID WorldSid, CreatorSid, AdminSid, SystemSid; + UCHAR KeyValueBuffer[0x40]; + PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo; + UNICODE_STRING KeyName; + ULONG ProtectionMode = 0; + OBJECT_ATTRIBUTES ObjectAttributes; + PACL Dacl; + PACCESS_ALLOWED_ACE Ace; + HANDLE hKey; + NTSTATUS Status; + ULONG ResultLength, SidLength, AclLength; + + /* Create the SD */ + Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION); + ASSERT(NT_SUCCESS(Status)); + + /* Initialize the System SID */ + Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, + &SystemSid); + ASSERT(NT_SUCCESS(Status)); + + /* Initialize the World SID */ + Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1, + SECURITY_WORLD_RID, + 0, 0, 0, 0, 0, 0, 0, + &WorldSid); + ASSERT(NT_SUCCESS(Status)); + + /* Initialize the Admin SID */ + Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &AdminSid); + ASSERT(NT_SUCCESS(Status)); + + /* Initialize the Creator SID */ + Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1, + SECURITY_CREATOR_OWNER_RID, + 0, 0, 0, 0, 0, 0, 0, + &CreatorSid); + ASSERT(NT_SUCCESS(Status)); + + /* Open the Session Manager Key */ + RtlInitUnicodeString(&KeyName, SM_REG_KEY); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + /* Read the key value */ + RtlInitUnicodeString(&KeyName, L"ProtectionMode"); + Status = NtQueryValueKey(hKey, + &KeyName, + KeyValuePartialInformation, + KeyValueBuffer, + sizeof(KeyValueBuffer), + &ResultLength); + + /* Make sure it's what we expect it to be */ + KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer; + if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) && + (*(PULONG)KeyValuePartialInfo->Data)) + { + /* Save the Protection Mode */ + ProtectionMode = *(PULONG)KeyValuePartialInfo->Data; + } + + /* Close the handle */ + NtClose(hKey); + } + + /* Check the Protection Mode */ + if (ProtectionMode & 3) + { + /* Calculate SID Lengths */ + SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) + + RtlLengthSid(AdminSid); + AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength; + + /* Allocate memory for the DACL */ + Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength); + ASSERT(Dacl != NULL); + + /* Build the ACL and add 3 ACEs */ + Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid); + ASSERT(NT_SUCCESS(Status)); + + /* Edit the ACEs to make them inheritable */ + Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace); + ASSERT(NT_SUCCESS(Status)); + Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; + Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace); + ASSERT(NT_SUCCESS(Status)); + Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; + Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); + ASSERT(NT_SUCCESS(Status)); + Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; + + /* Set this DACL with the SD */ + Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); + ASSERT(NT_SUCCESS(Status)); + goto Quickie; + } + else + { + /* Calculate SID Lengths */ + SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid); + AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength; + + /* Allocate memory for the DACL */ + Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength); + ASSERT(Dacl != NULL); + + /* Build the ACL and add 3 ACEs */ + Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); + ASSERT(NT_SUCCESS(Status)); + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid); + ASSERT(NT_SUCCESS(Status)); + + /* Edit the last ACE to make it inheritable */ + Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); + ASSERT(NT_SUCCESS(Status)); + Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; + + /* Set this DACL with the SD */ + Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); + ASSERT(NT_SUCCESS(Status)); + goto Quickie; + } + +/* FIXME: failure cases! Fail: */ + /* Free the memory */ + RtlFreeHeap(CsrHeap, 0, Dacl); + +/* FIXME: semi-failure cases! Quickie: */ +Quickie: + /* Free the SIDs */ + RtlFreeSid(SystemSid); + RtlFreeSid(WorldSid); + RtlFreeSid(AdminSid); + RtlFreeSid(CreatorSid); + + /* Return */ + return Status; +} + +/*++ + * @name FreeDosDevicesProtection + * + * The FreeDosDevicesProtection frees the security descriptor that was created + * by GetDosDevicesProtection + * + * @param DosDevicesSd + * Pointer to the security descriptor to free. + + * @return None. + * + * @remarks None. + * + *--*/ +VOID +NTAPI +FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd) +{ + PACL Dacl; + BOOLEAN Present, Default; + NTSTATUS Status; + + /* Get the DACL corresponding to this SD */ + Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default); + ASSERT(NT_SUCCESS(Status)); + ASSERT(Present); + ASSERT(Dacl != NULL); + + /* Free it */ + if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl); +} + +/*++ + * @name CsrCreateSessionObjectDirectory + * + * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects, + * Session and Dos Devices directories for the specified session. + * + * @param Session + * Session ID for which to create the directories. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * othwerwise. + * + * @remarks None. + * + *--*/ +NTSTATUS +NTAPI +CsrCreateSessionObjectDirectory(IN ULONG Session) +{ + WCHAR SessionBuffer[512], BnoBuffer[512]; + UNICODE_STRING SessionString, BnoString; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE BnoHandle; + SECURITY_DESCRIPTOR DosDevicesSd; + NTSTATUS Status; + + /* Generate the Session BNOLINKS Directory name */ + swprintf(SessionBuffer, L"%ws\BNOLINKS", SESSION_ROOT); + RtlInitUnicodeString(&SessionString, SessionBuffer); + + /* Create it */ + InitializeObjectAttributes(&ObjectAttributes, + &SessionString, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtCreateDirectoryObject(&BNOLinksDirectory, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: NtCreateDirectoryObject failed in " + "CsrCreateSessionObjectDirectory - status = %lx\n", Status); + return Status; + } + + /* Now add the Session ID */ + swprintf(SessionBuffer, L"%ld", Session); + RtlInitUnicodeString(&SessionString, SessionBuffer); + + /* Check if this is the first Session */ + if (Session) + { + /* Not the first, so the name will be slighly more complex */ + swprintf(BnoBuffer, L"%ws\%ld\BaseNamedObjects", SESSION_ROOT, Session); + RtlInitUnicodeString(&BnoString, BnoBuffer); + } + else + { + /* Use the direct name */ + RtlInitUnicodeString(&BnoString, L"\BaseNamedObjects"); + } + + /* Create the symlink */ + InitializeObjectAttributes(&ObjectAttributes, + &SessionString, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, + BNOLinksDirectory, + NULL); + Status = NtCreateSymbolicLinkObject(&BnoHandle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes, + &BnoString); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in " + "CsrCreateSessionObjectDirectory - status = %lx\n", Status); + return Status; + } + + /* Create the \DosDevices Security Descriptor */ + Status = GetDosDevicesProtection(&DosDevicesSd); + if (!NT_SUCCESS(Status)) return Status; + + /* Now create a directory for this session */ + swprintf(SessionBuffer, L"%ws\%ld", SESSION_ROOT, Session); + RtlInitUnicodeString(&SessionString, SessionBuffer); + + /* Create the directory */ + InitializeObjectAttributes(&ObjectAttributes, + &SessionString, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, + 0, + &DosDevicesSd); + Status = NtCreateDirectoryObject(&SessionObjectDirectory, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: NtCreateDirectoryObject failed in " + "CsrCreateSessionObjectDirectory - status = %lx\n", Status); + FreeDosDevicesProtection(&DosDevicesSd); + return Status; + } + + /* Next, create a directory for this session's DOS Devices */ + RtlInitUnicodeString(&SessionString, L"DosDevices"); + InitializeObjectAttributes(&ObjectAttributes, + &SessionString, + OBJ_CASE_INSENSITIVE, + SessionObjectDirectory, + &DosDevicesSd); + Status = NtCreateDirectoryObject(&DosDevicesDirectory, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: NtCreateDirectoryObject failed in " + "CsrCreateSessionObjectDirectory - status = %lx\n", Status); + } + + /* Release the Security Descriptor */ + FreeDosDevicesProtection(&DosDevicesSd); + + /* Return */ + return Status; +} + +/*++ + * @name CsrParseServerCommandLine + * + * The CsrParseServerCommandLine routine parses the CSRSS command-line in the + * registry and performs operations for each entry found. + * + * @param ArgumentCount + * Number of arguments on the command line. + * + * @param Arguments + * Array of arguments. + * + * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL + * othwerwise. + * + * @remarks None. + * + *--*/ +NTSTATUS +FASTCALL +CsrParseServerCommandLine(IN ULONG ArgumentCount, + IN PCHAR Arguments[]) +{ + NTSTATUS Status; + PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString; + ULONG i, DllIndex; + ANSI_STRING AnsiString; + OBJECT_ATTRIBUTES ObjectAttributes; + + /* Set the Defaults */ + CsrTotalPerProcessDataLength = 0; + CsrObjectDirectory = NULL; + CsrMaxApiRequestThreads = 16; + + /* Save our Session ID, and create a Directory for it */ + SessionId = NtCurrentPeb()->SessionId; + Status = CsrCreateSessionObjectDirectory(SessionId); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n", + Status); + + /* It's not fatal if the session ID isn't zero */ + if (SessionId) return Status; + ASSERT(NT_SUCCESS(Status)); + } + + /* Loop through every argument */ + for (i = 1; i < ArgumentCount; i++) + { + /* Split Name and Value */ + ParameterName = Arguments[i]; + DPRINT1("Name: %s\n", ParameterName); + ParameterValue = NULL; + ParameterValue = strchr(ParameterName, '='); + if (ParameterValue) *ParameterValue++ = ANSI_NULL; + DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue); + + /* Check for Object Directory */ + if (!_stricmp(ParameterName, "ObjectDirectory")) + { + /* Check if a session ID is specified */ + if (SessionId) + { + DPRINT1("Sessions not yet implemented\n"); + ASSERT(SessionId); + } + + /* Initialize the directory name */ + RtlInitAnsiString(&AnsiString, ParameterValue); + Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName, + &AnsiString, + TRUE); + ASSERT(NT_SUCCESS(Status) || SessionId != 0); + if (!NT_SUCCESS(Status)) return Status; + + /* Create it */ + InitializeObjectAttributes(&ObjectAttributes, + &CsrDirectoryName, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, + NULL, + NULL); + Status = NtCreateDirectoryObject(&CsrObjectDirectory, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) return Status; + + /* Secure it */ + Status = CsrSetDirectorySecurity(CsrObjectDirectory); + if (!NT_SUCCESS(Status)) return Status; + } + else if (!_stricmp(ParameterName, "SubSystemType")) + { + /* Ignored */ + } + else if (!_stricmp(ParameterName, "MaxRequestThreads")) + { + Status = RtlCharToInteger(ParameterValue, + 0, + &CsrMaxApiRequestThreads); + } + else if (!_stricmp(ParameterName, "RequestThreads")) + { + /* Ignored */ + Status = STATUS_SUCCESS; + } + else if (!_stricmp(ParameterName, "ProfileControl")) + { + /* Ignored */ + } + else if (!_stricmp(ParameterName, "SharedSection")) + { + /* Create 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 */ + BasepFakeStaticServerData(); + #if 0 + Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER); + #endif + } + else if (!_stricmp(ParameterName, "ServerDLL")) + { + /* Loop the command line */ + EntryPoint = NULL; + Status = STATUS_INVALID_PARAMETER; + ServerString = ParameterValue; + while (*ServerString) + { + /* Check for the Entry Point */ + if ((*ServerString == ':') && (!EntryPoint)) + { + /* Found it. Add a nullchar and save it */ + *ServerString++ = ANSI_NULL; + EntryPoint = ServerString; + } + + /* Check for the Dll Index */ + if (*ServerString++ == ',') break; + } + + /* Did we find something to load? */ + if (!*ServerString) + { + DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n", + ParameterValue, Status); + return Status; + } + + /* Convert it to a ULONG */ + Status = RtlCharToInteger(ServerString, 10, &DllIndex); + + /* Add a null char if it was valid */ + if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL; + + /* Load it */ + if (CsrDebug & 1) DPRINT1("CSRSS: Should be loading ServerDll=%s:%s\n", ParameterValue, EntryPoint); + Status = STATUS_SUCCESS; + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n", + ParameterValue, Status); + return Status; + } + } + else if (!_stricmp(ParameterName, "Windows")) + { + /* Ignored */ + } + else + { + /* Invalid parameter on the command line */ + Status = STATUS_INVALID_PARAMETER; + } + } + + /* Return status */ + return Status; +}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -514,26 +905,63 @@ CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]) { - UINT i = 0; NTSTATUS Status = STATUS_SUCCESS;
DPRINT("CSR: %s called\n", __FUNCTION__);
- for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++) - { - Status = InitRoutine[i].EntryPoint(ArgumentCount,Arguments,NULL); - if(!NT_SUCCESS(Status)) - { - DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n", - __FUNCTION__, - InitRoutine[i].ErrorMessage, - Status); - if (InitRoutine[i].Required) - { - return FALSE; - } - } - } + Status = CsrpCreateHeap(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateHeap", Status); + } + + /* Parse the command line */ + Status = CsrParseServerCommandLine(ArgumentCount, Arguments); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n", + __FUNCTION__, Status); + return Status; + } + + CsrInitProcessData(); + + Status = CsrpCreateListenPort(L"\Windows\ApiPort", &hApiPort, (PTHREAD_START_ROUTINE)ClientConnectionThread); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateApiPort", Status); + } + + Status = CsrApiRegisterDefinitions(NativeDefinitions); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrApiRegisterDefinitions", Status); + } + + Status = CsrpInitWin32Csr(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpInitWin32Csr", Status); + } + + Status = CsrpCreateListenPort(L"\Windows\SbApiPort", &hSbApiPort, ServerSbApiPortThread); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateCallbackPort", Status); + } + + Status = CsrpRegisterSubsystem(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpRegisterSubsystem", Status); + } + + Status = NtSetDefaultHardErrorPort(hApiPort); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateHardErrorPort", Status); + } + if (CallInitComplete()) { return STATUS_SUCCESS;
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/procsup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csrs... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/csrsrv/procsup.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/csrsrv/procsup.c [iso-8859-1] Wed Feb 15 16:11:12 2012 @@ -16,7 +16,6 @@
#define LOCK RtlEnterCriticalSection(&ProcessDataLock) #define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock) -#define CsrHeap RtlGetProcessHeap()
#define CsrAcquireProcessLock() LOCK #define CsrReleaseProcessLock() UNLOCK
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/srv.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csrs... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/csrsrv/srv.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/csrsrv/srv.h [iso-8859-1] Wed Feb 15 16:11:12 2012 @@ -4,16 +4,7 @@ #define WIN32_NO_STATUS #include <windows.h> #include <winnt.h> -#include <ndk/exfuncs.h> -#include <ndk/iofuncs.h> -#include <ndk/kefuncs.h> -#include <ndk/lpcfuncs.h> -#include <ndk/ldrfuncs.h> -#include <ndk/mmfuncs.h> -#include <ndk/obfuncs.h> -#include <ndk/setypes.h> -#include <ndk/sefuncs.h> -#include <ndk/umfuncs.h> +#include <ndk/ntndk.h>
/* CSR Header */ //#include <csr/server.h> @@ -29,6 +20,18 @@ #include <api.h> #include <csrplugin.h>
+extern HANDLE CsrHeap; + +#define SM_REG_KEY \ + L"\Registry\Machine\System\CurrentControlSet\Control\Session Manager" + +#define SESSION_ROOT L"\Sessions" +#define GLOBAL_ROOT L"\GLOBAL??" +#define SYMLINK_NAME L"SymbolicLink" +#define SB_PORT_NAME L"SbAbiPort" +#define CSR_PORT_NAME L"ApiPort" +#define UNICODE_PATH_SEP L"\" + /* Defines */ #define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align)) #define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
Modified: trunk/reactos/subsystems/win32/csrss/csrss.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csrs... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/csrss.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/csrss.c [iso-8859-1] Wed Feb 15 16:11:12 2012 @@ -11,6 +11,8 @@
#define WIN32_NO_STATUS #include <windows.h> +#define NTOS_MODE_USER +#include <ndk/ntndk.h> #include <api.h> #define NDEBUG #include <debug.h> @@ -39,12 +41,34 @@ { KPRIORITY BasePriority = (8 + 1) + 4; NTSTATUS Status; + //ULONG Response; + UNREFERENCED_PARAMETER(envp); + UNREFERENCED_PARAMETER(DebugFlag);
/* Set the Priority */ NtSetInformationProcess(NtCurrentProcess(), ProcessBasePriority, &BasePriority, sizeof(KPRIORITY)); + + /* Give us IOPL so that we can access the VGA registers */ + Status = NtSetInformationProcess(NtCurrentProcess(), + ProcessUserModeIOPL, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + /* Raise a hard error */ + DPRINT1("CSRSS: Could not raise IOPL: %x\n", Status); + #if 0 + Status = NtRaiseHardError(STATUS_IO_PRIVILEGE_FAILED, + 0, + 0, + NULL, + OptionOk, + &Response); + #endif + }
/* Initialize CSR through CSRSRV */ Status = CsrServerInitialization(argc, argv); @@ -62,7 +86,7 @@ if (!NtCurrentPeb()->SessionId) RtlSetProcessIsCritical(TRUE, NULL, FALSE);
/* Kill this thread. CSRSRV keeps us going */ - NtTerminateThread (NtCurrentThread(), Status); + NtTerminateThread(NtCurrentThread(), Status); return 0; }