ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

init.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS CSR Sub System
00004  * FILE:            subsystems/win32/csrss/csrsrv/init.c
00005  * PURPOSE:         CSR Server DLL Initialization
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  */
00008 
00009 /* INCLUDES *******************************************************************/
00010 
00011 #include "srv.h"
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* DATA ***********************************************************************/
00016 
00017 HANDLE CsrHeap = (HANDLE) 0;
00018 HANDLE CsrObjectDirectory = (HANDLE) 0;
00019 UNICODE_STRING CsrDirectoryName;
00020 UNICODE_STRING CsrSbApiPortName;
00021 HANDLE CsrSbApiPort = 0;
00022 PCSR_THREAD CsrSbApiRequestThreadPtr;
00023 HANDLE CsrSmApiPort;
00024 HANDLE hSbApiPort = (HANDLE) 0;
00025 HANDLE CsrApiPort = (HANDLE) 0;
00026 ULONG CsrDebug = 0;//0xFFFFFFFF;
00027 ULONG CsrMaxApiRequestThreads;
00028 ULONG CsrTotalPerProcessDataLength;
00029 ULONG SessionId;
00030 HANDLE BNOLinksDirectory;
00031 HANDLE SessionObjectDirectory;
00032 HANDLE DosDevicesDirectory;
00033 HANDLE CsrInitializationEvent;
00034 SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
00035 
00036 /* PRIVATE FUNCTIONS **********************************************************/
00037 
00038 VOID
00039 CallHardError(IN PCSR_THREAD ThreadData,
00040               IN PHARDERROR_MSG HardErrorMessage)
00041 {
00042     unsigned i;
00043     PCSR_SERVER_DLL ServerDll;
00044 
00045     DPRINT("CSR: %s called\n", __FUNCTION__);
00046 
00047     /* Notify the Server DLLs */
00048     for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
00049     {
00050         /* Get the current Server DLL */
00051         ServerDll = CsrLoadedServerDll[i];
00052 
00053         /* Make sure it's valid and that it has callback */
00054         if ((ServerDll) && (ServerDll->HardErrorCallback))
00055         {
00056             ServerDll->HardErrorCallback(ThreadData, HardErrorMessage);
00057         }
00058     }
00059 }
00060 
00061 NTSTATUS
00062 CallProcessCreated(IN PCSR_PROCESS SourceProcessData,
00063                    IN PCSR_PROCESS TargetProcessData)
00064 {
00065     NTSTATUS Status = STATUS_SUCCESS;
00066     unsigned i;
00067     PCSR_SERVER_DLL ServerDll;
00068 
00069     DPRINT("CSR: %s called\n", __FUNCTION__);
00070 
00071     /* Notify the Server DLLs */
00072     for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
00073     {
00074         /* Get the current Server DLL */
00075         ServerDll = CsrLoadedServerDll[i];
00076 
00077         /* Make sure it's valid and that it has callback */
00078         if ((ServerDll) && (ServerDll->NewProcessCallback))
00079         {
00080             Status = ServerDll->NewProcessCallback(SourceProcessData, TargetProcessData);
00081         }
00082     }
00083 
00084     return Status;
00085 }
00086 
00087 CSRSS_API_DEFINITION NativeDefinitions[] =
00088   {
00089     CSRSS_DEFINE_API(CREATE_PROCESS,               CsrSrvCreateProcess),
00090     CSRSS_DEFINE_API(CREATE_THREAD,                CsrSrvCreateThread),
00091     CSRSS_DEFINE_API(TERMINATE_PROCESS,            CsrTerminateProcess),
00092     CSRSS_DEFINE_API(CONNECT_PROCESS,              CsrConnectProcess),
00093     CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS,    CsrRegisterServicesProcess),
00094     CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS,      CsrGetShutdownParameters),
00095     CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS,      CsrSetShutdownParameters),
00096     { 0, 0, NULL }
00097   };
00098 
00099 /* === INIT ROUTINES === */
00100 
00101 VOID
00102 WINAPI
00103 BasepFakeStaticServerData(VOID);
00104 
00105 /*++
00106  * @name CsrSetProcessSecurity
00107  *
00108  * The CsrSetProcessSecurity routine protects access to the CSRSS process
00109  * from unauthorized tampering.
00110  *
00111  * @param None.
00112  *
00113  * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
00114  *         othwerwise.
00115  *
00116  * @remarks None.
00117  *
00118  *--*/
00119 NTSTATUS
00120 NTAPI
00121 CsrSetProcessSecurity(VOID)
00122 {
00123     NTSTATUS Status;
00124     HANDLE hToken, hProcess = NtCurrentProcess();
00125     ULONG Length;
00126     PTOKEN_USER TokenInfo = NULL;
00127     PSECURITY_DESCRIPTOR ProcSd = NULL;
00128     PACL Dacl;
00129     PSID UserSid;
00130 
00131     /* Open our token */
00132     Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
00133     if (!NT_SUCCESS(Status)) goto Quickie;
00134 
00135     /* Get the Token User Length */
00136     NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);
00137 
00138     /* Allocate space for it */
00139     TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
00140     if (!TokenInfo)
00141     {
00142         Status = STATUS_NO_MEMORY;
00143         goto Quickie;
00144     }
00145 
00146     /* Now query the data */
00147     Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length);
00148     NtClose(hToken);
00149     if (!NT_SUCCESS(Status)) goto Quickie;
00150 
00151     /* Now check the SID Length */
00152     UserSid = TokenInfo->User.Sid;
00153     Length = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
00154 
00155     /* Allocate a buffer for the Security Descriptor, with SID and DACL */
00156     ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
00157     if (!ProcSd)
00158     {
00159         Status = STATUS_NO_MEMORY;
00160         goto Quickie;
00161     }
00162 
00163     /* Set the pointer to the DACL */
00164     Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
00165 
00166     /* Now create the SD itself */
00167     Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION);
00168     if (!NT_SUCCESS(Status))
00169     {
00170         DPRINT1("CSRSS: SD creation failed - status = %lx\n", Status);
00171         goto Quickie;
00172     }
00173 
00174     /* Create the DACL for it*/
00175     Status = RtlCreateAcl(Dacl, Length, ACL_REVISION2);
00176     if (!NT_SUCCESS(Status))
00177     {
00178         DPRINT1("CSRSS: DACL creation failed - status = %lx\n", Status);
00179         goto Quickie;
00180     }
00181 
00182     /* Create the ACE */
00183     Status = RtlAddAccessAllowedAce(Dacl,
00184                                     ACL_REVISION,
00185                                     PROCESS_VM_READ | PROCESS_VM_WRITE |
00186                                     PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
00187                                     PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
00188                                     PROCESS_QUERY_INFORMATION | READ_CONTROL,
00189                                     UserSid);
00190     if (!NT_SUCCESS(Status))
00191     {
00192         DPRINT1("CSRSS: ACE creation failed - status = %lx\n", Status);
00193         goto Quickie;
00194     }
00195 
00196     /* Clear the DACL in the SD */
00197     Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
00198     if (!NT_SUCCESS(Status))
00199     {
00200         DPRINT1("CSRSS: set DACL failed - status = %lx\n", Status);
00201         goto Quickie;
00202     }
00203 
00204     /* Write the SD into the Process */
00205     Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
00206     if (!NT_SUCCESS(Status))
00207     {
00208         DPRINT1("CSRSS: set process DACL failed - status = %lx\n", Status);
00209         goto Quickie;
00210     }
00211 
00212     /* Free the memory and return */
00213 Quickie:
00214     if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
00215     RtlFreeHeap(CsrHeap, 0, TokenInfo);
00216     return Status;
00217 }
00218 
00219 /*++
00220  * @name CsrSetDirectorySecurity
00221  *
00222  * The CsrSetDirectorySecurity routine sets the security descriptor for the
00223  * specified Object Directory.
00224  *
00225  * @param ObjectDirectory
00226  *        Handle fo the Object Directory to protect.
00227  *
00228  * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
00229  *         othwerwise.
00230  *
00231  * @remarks None.
00232  *
00233  *--*/
00234 NTSTATUS
00235 NTAPI
00236 CsrSetDirectorySecurity(IN HANDLE ObjectDirectory)
00237 {
00238     /* FIXME: Implement */
00239     return STATUS_SUCCESS;
00240 }
00241 
00242 /*++
00243  * @name GetDosDevicesProtection
00244  *
00245  * The GetDosDevicesProtection creates a security descriptor for the DOS Devices
00246  * Object Directory.
00247  *
00248  * @param DosDevicesSd
00249  *        Pointer to the Security Descriptor to return.
00250  *
00251  * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
00252  *         othwerwise.
00253  *
00254  * @remarks Depending on the DOS Devices Protection Mode (set in the registry),
00255  *          regular users may or may not have full access to the directory.
00256  *
00257  *--*/
00258 NTSTATUS
00259 NTAPI
00260 GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
00261 {
00262     SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
00263     SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY};
00264     SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
00265     PSID WorldSid, CreatorSid, AdminSid, SystemSid;
00266     UCHAR KeyValueBuffer[0x40];
00267     PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
00268     UNICODE_STRING KeyName;
00269     ULONG ProtectionMode = 0;
00270     OBJECT_ATTRIBUTES ObjectAttributes;
00271     PACL Dacl;
00272     PACCESS_ALLOWED_ACE Ace;
00273     HANDLE hKey;
00274     NTSTATUS Status;
00275     ULONG ResultLength, SidLength, AclLength;
00276 
00277     /* Create the SD */
00278     Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION);
00279     ASSERT(NT_SUCCESS(Status));
00280 
00281     /* Initialize the System SID */
00282     Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
00283                                          SECURITY_LOCAL_SYSTEM_RID,
00284                                          0, 0, 0, 0, 0, 0, 0,
00285                                          &SystemSid);
00286     ASSERT(NT_SUCCESS(Status));
00287 
00288     /* Initialize the World SID */
00289     Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1,
00290                                          SECURITY_WORLD_RID,
00291                                          0, 0, 0, 0, 0, 0, 0,
00292                                          &WorldSid);
00293     ASSERT(NT_SUCCESS(Status));
00294 
00295     /* Initialize the Admin SID */
00296     Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2,
00297                                          SECURITY_BUILTIN_DOMAIN_RID,
00298                                          DOMAIN_ALIAS_RID_ADMINS,
00299                                          0, 0, 0, 0, 0, 0,
00300                                          &AdminSid);
00301     ASSERT(NT_SUCCESS(Status));
00302 
00303     /* Initialize the Creator SID */
00304     Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
00305                                          SECURITY_CREATOR_OWNER_RID,
00306                                          0, 0, 0, 0, 0, 0, 0,
00307                                          &CreatorSid);
00308     ASSERT(NT_SUCCESS(Status));
00309 
00310     /* Open the Session Manager Key */
00311     RtlInitUnicodeString(&KeyName, SM_REG_KEY);
00312     InitializeObjectAttributes(&ObjectAttributes,
00313                                &KeyName,
00314                                OBJ_CASE_INSENSITIVE,
00315                                NULL,
00316                                NULL);
00317     Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
00318     if (NT_SUCCESS(Status))
00319     {
00320         /* Read the key value */
00321         RtlInitUnicodeString(&KeyName, L"ProtectionMode");
00322         Status = NtQueryValueKey(hKey,
00323                                  &KeyName,
00324                                  KeyValuePartialInformation,
00325                                  KeyValueBuffer,
00326                                  sizeof(KeyValueBuffer),
00327                                  &ResultLength);
00328 
00329         /* Make sure it's what we expect it to be */
00330         KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
00331         if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
00332             (*(PULONG)KeyValuePartialInfo->Data))
00333         {
00334             /* Save the Protection Mode */
00335             ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
00336         }
00337 
00338         /* Close the handle */
00339         NtClose(hKey);
00340     }
00341 
00342     /* Check the Protection Mode */
00343     if (ProtectionMode & 3)
00344     {
00345         /* Calculate SID Lengths */
00346         SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) +
00347                     RtlLengthSid(AdminSid);
00348         AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
00349 
00350         /* Allocate memory for the DACL */
00351         Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
00352         ASSERT(Dacl != NULL);
00353 
00354         /* Build the ACL and add 3 ACEs */
00355         Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
00356         ASSERT(NT_SUCCESS(Status));
00357         Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
00358         ASSERT(NT_SUCCESS(Status));
00359         Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid);
00360         ASSERT(NT_SUCCESS(Status));
00361         Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid);
00362         ASSERT(NT_SUCCESS(Status));
00363 
00364         /* Edit the ACEs to make them inheritable */
00365         Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace);
00366         ASSERT(NT_SUCCESS(Status));
00367         Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
00368         Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace);
00369         ASSERT(NT_SUCCESS(Status));
00370         Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
00371         Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
00372         ASSERT(NT_SUCCESS(Status));
00373         Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
00374 
00375         /* Set this DACL with the SD */
00376         Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
00377         ASSERT(NT_SUCCESS(Status));
00378         goto Quickie;
00379     }
00380     else
00381     {
00382         /* Calculate SID Lengths */
00383         SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid);
00384         AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
00385 
00386         /* Allocate memory for the DACL */
00387         Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
00388         ASSERT(Dacl != NULL);
00389 
00390         /* Build the ACL and add 3 ACEs */
00391         Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
00392         ASSERT(NT_SUCCESS(Status));
00393         Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid);
00394         ASSERT(NT_SUCCESS(Status));
00395         Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
00396         ASSERT(NT_SUCCESS(Status));
00397         Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid);
00398         ASSERT(NT_SUCCESS(Status));
00399 
00400         /* Edit the last ACE to make it inheritable */
00401         Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
00402         ASSERT(NT_SUCCESS(Status));
00403         Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
00404 
00405         /* Set this DACL with the SD */
00406         Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
00407         ASSERT(NT_SUCCESS(Status));
00408         goto Quickie;
00409     }
00410 
00411 /* FIXME: failure cases! Fail: */
00412     /* Free the memory */
00413     RtlFreeHeap(CsrHeap, 0, Dacl);
00414 
00415 /* FIXME: semi-failure cases! Quickie: */
00416 Quickie:
00417     /* Free the SIDs */
00418     RtlFreeSid(SystemSid);
00419     RtlFreeSid(WorldSid);
00420     RtlFreeSid(AdminSid);
00421     RtlFreeSid(CreatorSid);
00422 
00423     /* Return */
00424     return Status;
00425 }
00426 
00427 /*++
00428  * @name FreeDosDevicesProtection
00429  *
00430  * The FreeDosDevicesProtection frees the security descriptor that was created
00431  * by GetDosDevicesProtection
00432  *
00433  * @param DosDevicesSd
00434  *        Pointer to the security descriptor to free.
00435 
00436  * @return None.
00437  *
00438  * @remarks None.
00439  *
00440  *--*/
00441 VOID
00442 NTAPI
00443 FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd)
00444 {
00445     PACL Dacl;
00446     BOOLEAN Present, Default;
00447     NTSTATUS Status;
00448 
00449     /* Get the DACL corresponding to this SD */
00450     Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default);
00451     ASSERT(NT_SUCCESS(Status));
00452     ASSERT(Present);
00453     ASSERT(Dacl != NULL);
00454 
00455     /* Free it */
00456     if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl);
00457 }
00458 
00459 /*++
00460  * @name CsrCreateSessionObjectDirectory
00461  *
00462  * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects,
00463  * Session and Dos Devices directories for the specified session.
00464  *
00465  * @param Session
00466  *        Session ID for which to create the directories.
00467  *
00468  * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
00469  *         othwerwise.
00470  *
00471  * @remarks None.
00472  *
00473  *--*/
00474 NTSTATUS
00475 NTAPI
00476 CsrCreateSessionObjectDirectory(IN ULONG Session)
00477 {
00478     WCHAR SessionBuffer[512], BnoBuffer[512];
00479     UNICODE_STRING SessionString, BnoString;
00480     OBJECT_ATTRIBUTES ObjectAttributes;
00481     HANDLE BnoHandle;
00482     SECURITY_DESCRIPTOR DosDevicesSd;
00483     NTSTATUS Status;
00484 
00485     /* Generate the Session BNOLINKS Directory name */
00486     swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT);
00487     RtlInitUnicodeString(&SessionString, SessionBuffer);
00488 
00489     /* Create it */
00490     InitializeObjectAttributes(&ObjectAttributes,
00491                                &SessionString,
00492                                OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
00493                                NULL,
00494                                NULL);
00495     Status = NtCreateDirectoryObject(&BNOLinksDirectory,
00496                                      DIRECTORY_ALL_ACCESS,
00497                                      &ObjectAttributes);
00498     if (!NT_SUCCESS(Status))
00499     {
00500         DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
00501                 "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
00502         return Status;
00503     }
00504 
00505     /* Now add the Session ID */
00506     swprintf(SessionBuffer, L"%ld", Session);
00507     RtlInitUnicodeString(&SessionString, SessionBuffer);
00508 
00509     /* Check if this is the first Session */
00510     if (Session)
00511     {
00512         /* Not the first, so the name will be slighly more complex */
00513         swprintf(BnoBuffer, L"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT, Session);
00514         RtlInitUnicodeString(&BnoString, BnoBuffer);
00515     }
00516     else
00517     {
00518         /* Use the direct name */
00519         RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
00520     }
00521 
00522     /* Create the symlink */
00523     InitializeObjectAttributes(&ObjectAttributes,
00524                                &SessionString,
00525                                OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
00526                                BNOLinksDirectory,
00527                                NULL);
00528     Status = NtCreateSymbolicLinkObject(&BnoHandle,
00529                                         SYMBOLIC_LINK_ALL_ACCESS,
00530                                         &ObjectAttributes,
00531                                         &BnoString);
00532     if (!NT_SUCCESS(Status))
00533     {
00534         DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in "
00535                 "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
00536         return Status;
00537     }
00538 
00539     /* Create the \DosDevices Security Descriptor */
00540     Status = GetDosDevicesProtection(&DosDevicesSd);
00541     if (!NT_SUCCESS(Status)) return Status;
00542 
00543     /* Now create a directory for this session */
00544     swprintf(SessionBuffer, L"%ws\\%ld", SESSION_ROOT, Session);
00545     RtlInitUnicodeString(&SessionString, SessionBuffer);
00546 
00547     /* Create the directory */
00548     InitializeObjectAttributes(&ObjectAttributes,
00549                                &SessionString,
00550                                OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
00551                                0,
00552                                &DosDevicesSd);
00553     Status = NtCreateDirectoryObject(&SessionObjectDirectory,
00554                                      DIRECTORY_ALL_ACCESS,
00555                                      &ObjectAttributes);
00556     if (!NT_SUCCESS(Status))
00557     {
00558         DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
00559                 "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
00560         FreeDosDevicesProtection(&DosDevicesSd);
00561         return Status;
00562     }
00563 
00564     /* Next, create a directory for this session's DOS Devices */
00565     RtlInitUnicodeString(&SessionString, L"DosDevices");
00566     InitializeObjectAttributes(&ObjectAttributes,
00567                                &SessionString,
00568                                OBJ_CASE_INSENSITIVE,
00569                                SessionObjectDirectory,
00570                                &DosDevicesSd);
00571     Status = NtCreateDirectoryObject(&DosDevicesDirectory,
00572                                      DIRECTORY_ALL_ACCESS,
00573                                      &ObjectAttributes);
00574     if (!NT_SUCCESS(Status))
00575     {
00576         DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
00577                 "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
00578     }
00579 
00580     /* Release the Security Descriptor */
00581     FreeDosDevicesProtection(&DosDevicesSd);
00582 
00583     /* Return */
00584     return Status;
00585 }
00586 
00587 /*++
00588  * @name CsrParseServerCommandLine
00589  *
00590  * The CsrParseServerCommandLine routine parses the CSRSS command-line in the
00591  * registry and performs operations for each entry found.
00592  *
00593  * @param ArgumentCount
00594  *        Number of arguments on the command line.
00595  *
00596  * @param Arguments
00597  *        Array of arguments.
00598  *
00599  * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
00600  *         othwerwise.
00601  *
00602  * @remarks None.
00603  *
00604  *--*/
00605 NTSTATUS
00606 FASTCALL
00607 CsrParseServerCommandLine(IN ULONG ArgumentCount,
00608                           IN PCHAR Arguments[])
00609 {
00610     NTSTATUS Status;
00611     PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString;
00612     ULONG i, DllIndex;
00613     ANSI_STRING AnsiString;
00614     OBJECT_ATTRIBUTES ObjectAttributes;
00615 
00616     /* Set the Defaults */
00617     CsrTotalPerProcessDataLength = 0;
00618     CsrObjectDirectory = NULL;
00619     CsrMaxApiRequestThreads = 16;
00620 
00621     /* Save our Session ID, and create a Directory for it */
00622     SessionId = NtCurrentPeb()->SessionId;
00623     Status = CsrCreateSessionObjectDirectory(SessionId);
00624     if (!NT_SUCCESS(Status))
00625     {
00626         DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
00627                 Status);
00628 
00629         /* It's not fatal if the session ID isn't zero */
00630         if (SessionId) return Status;
00631         ASSERT(NT_SUCCESS(Status));
00632     }
00633 
00634     /* Loop through every argument */
00635     for (i = 1; i < ArgumentCount; i++)
00636     {
00637         /* Split Name and Value */
00638         ParameterName = Arguments[i];
00639         ParameterValue = NULL;
00640         ParameterValue = strchr(ParameterName, '=');
00641         if (ParameterValue) *ParameterValue++ = ANSI_NULL;
00642 
00643         /* Check for Object Directory */
00644         if (!_stricmp(ParameterName, "ObjectDirectory"))
00645         {
00646             /* Check if a session ID is specified */
00647             if (SessionId)
00648             {
00649                 DPRINT1("Sessions not yet implemented\n");
00650                 ASSERT(SessionId);
00651             }
00652 
00653             /* Initialize the directory name */
00654             RtlInitAnsiString(&AnsiString, ParameterValue);
00655             Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName,
00656                                                   &AnsiString,
00657                                                   TRUE);
00658             ASSERT(NT_SUCCESS(Status) || SessionId != 0);
00659             if (!NT_SUCCESS(Status)) return Status;
00660 
00661             /* Create it */
00662             InitializeObjectAttributes(&ObjectAttributes,
00663                                        &CsrDirectoryName,
00664                                        OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
00665                                        NULL,
00666                                        NULL);
00667             Status = NtCreateDirectoryObject(&CsrObjectDirectory,
00668                                              DIRECTORY_ALL_ACCESS,
00669                                              &ObjectAttributes);
00670             if (!NT_SUCCESS(Status)) return Status;
00671 
00672             /* Secure it */
00673             Status = CsrSetDirectorySecurity(CsrObjectDirectory);
00674             if (!NT_SUCCESS(Status)) return Status;
00675         }
00676         else if (!_stricmp(ParameterName, "SubSystemType"))
00677         {
00678             /* Ignored */
00679         }
00680         else if (!_stricmp(ParameterName, "MaxRequestThreads"))
00681         {
00682             Status = RtlCharToInteger(ParameterValue,
00683                                       0,
00684                                       &CsrMaxApiRequestThreads);
00685         }
00686         else if (!_stricmp(ParameterName, "RequestThreads"))
00687         {
00688             /* Ignored */
00689             Status = STATUS_SUCCESS;
00690         }
00691         else if (!_stricmp(ParameterName, "ProfileControl"))
00692         {
00693             /* Ignored */
00694         }
00695         else if (!_stricmp(ParameterName, "SharedSection"))
00696         {
00697             /* Create the Section */
00698             Status = CsrSrvCreateSharedSection(ParameterValue);
00699             if (!NT_SUCCESS(Status))
00700             {
00701                 DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
00702                         ParameterName, ParameterValue, Status);
00703                 return Status;
00704             }
00705 
00706             /* Load us */
00707             Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER);
00708         }
00709         else if (!_stricmp(ParameterName, "ServerDLL"))
00710         {
00711             /* Loop the command line */
00712             EntryPoint = NULL;
00713             Status = STATUS_INVALID_PARAMETER;
00714             ServerString = ParameterValue;
00715             while (*ServerString)
00716             {
00717                 /* Check for the Entry Point */
00718                 if ((*ServerString == ':') && (!EntryPoint))
00719                 {
00720                     /* Found it. Add a nullchar and save it */
00721                     *ServerString++ = ANSI_NULL;
00722                     EntryPoint = ServerString;
00723                 }
00724 
00725                 /* Check for the Dll Index */
00726                 if (*ServerString++ == ',') break;
00727             }
00728 
00729             /* Did we find something to load? */
00730             if (!*ServerString)
00731             {
00732                 DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
00733                         ParameterValue, Status);
00734                 return Status;
00735             }
00736 
00737             /* Convert it to a ULONG */
00738             Status = RtlCharToInteger(ServerString, 10, &DllIndex);
00739 
00740             /* Add a null char if it was valid */
00741             if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL;
00742 
00743             /* Load it */
00744             if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint);
00745 
00746             /* Hackito ergo sum */
00747             Status = STATUS_SUCCESS;
00748             if (strstr(ParameterValue, "basesrv"))
00749             {
00750                 DPRINT1("Fake basesrv init\n");
00751                 BasepFakeStaticServerData();
00752             }
00753 //            else
00754 //            {
00755 //                Status = CsrLoadServerDll(ParameterValue, EntryPoint, 2);
00756 //            }
00757             if (!NT_SUCCESS(Status))
00758             {
00759                 DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n",
00760                         ParameterValue, Status);
00761                 return Status;
00762             }
00763         }
00764         else if (!_stricmp(ParameterName, "Windows"))
00765         {
00766             /* Ignored */
00767         }
00768         else
00769         {
00770             /* Invalid parameter on the command line */
00771             Status = STATUS_INVALID_PARAMETER;
00772         }
00773     }
00774 
00775     /* Return status */
00776     return Status;
00777 }
00778 
00779 /*++
00780  * @name CsrCreateLocalSystemSD
00781  *
00782  * The CsrCreateLocalSystemSD routine creates a Security Descriptor for
00783  * the local account with PORT_ALL_ACCESS.
00784  *
00785  * @param LocalSystemSd
00786  *        Pointer to a pointer to the security descriptor to create.
00787  *
00788  * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
00789  *         othwerwise.
00790  *
00791  * @remarks None.
00792  *
00793  *--*/
00794 NTSTATUS
00795 NTAPI
00796 CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
00797 {
00798     SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
00799     PSID SystemSid;
00800     ULONG Length;
00801     PSECURITY_DESCRIPTOR SystemSd;
00802     PACL Dacl;
00803     NTSTATUS Status;
00804 
00805     /* Initialize the System SID */
00806     RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
00807                                 SECURITY_LOCAL_SYSTEM_RID,
00808                                 0, 0, 0, 0, 0, 0, 0,
00809                                 &SystemSid);
00810 
00811     /* Get the length of the SID */
00812     Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
00813 
00814     /* Allocate a buffer for the Security Descriptor, with SID and DACL */
00815     SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
00816 
00817     /* Set the pointer to the DACL */
00818     Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
00819 
00820     /* Now create the SD itself */
00821     Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION);
00822     if (!NT_SUCCESS(Status))
00823     {
00824         /* Fail */
00825         RtlFreeHeap(CsrHeap, 0, SystemSd);
00826         return Status;
00827     }
00828 
00829     /* Create the DACL for it*/
00830     RtlCreateAcl(Dacl, Length, ACL_REVISION2);
00831 
00832     /* Create the ACE */
00833     Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid);
00834     if (!NT_SUCCESS(Status))
00835     {
00836         /* Fail */
00837         RtlFreeHeap(CsrHeap, 0, SystemSd);
00838         return Status;
00839     }
00840 
00841     /* Clear the DACL in the SD */
00842     Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE);
00843     if (!NT_SUCCESS(Status))
00844     {
00845         /* Fail */
00846         RtlFreeHeap(CsrHeap, 0, SystemSd);
00847         return Status;
00848     }
00849 
00850     /* Free the SID and return*/
00851     RtlFreeSid(SystemSid);
00852     *LocalSystemSd = SystemSd;
00853     return Status;
00854 }
00855 
00856 /*++
00857  * @name CsrSbApiPortInitialize
00858  *
00859  * The CsrSbApiPortInitialize routine initializes the LPC Port used for
00860  * communications with the Session Manager (SM) and initializes the static
00861  * thread that will handle connection requests and APIs.
00862  *
00863  * @param None
00864  *
00865  * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
00866  *         othwerwise.
00867  *
00868  * @remarks None.
00869  *
00870  *--*/
00871 NTSTATUS
00872 NTAPI
00873 CsrSbApiPortInitialize(VOID)
00874 {
00875     ULONG Size;
00876     PSECURITY_DESCRIPTOR PortSd;
00877     OBJECT_ATTRIBUTES ObjectAttributes;
00878     NTSTATUS Status;
00879     HANDLE hRequestThread;
00880     CLIENT_ID ClientId;
00881 
00882     /* Calculate how much space we'll need for the Port Name */
00883     Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR);
00884 
00885     /* Create the buffer for it */
00886     CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
00887     if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY;
00888 
00889     /* Setup the rest of the empty string */
00890     CsrSbApiPortName.Length = 0;
00891     CsrSbApiPortName.MaximumLength = (USHORT)Size;
00892 
00893     /* Now append the full port name */
00894     RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName);
00895     RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP);
00896     RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME);
00897     if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName);
00898 
00899     /* Create Security Descriptor for this Port */
00900     Status = CsrCreateLocalSystemSD(&PortSd);
00901     if (!NT_SUCCESS(Status)) return Status;
00902 
00903     /* Initialize the Attributes */
00904     InitializeObjectAttributes(&ObjectAttributes,
00905                                &CsrSbApiPortName,
00906                                0,
00907                                NULL,
00908                                PortSd);
00909 
00910     /* Create the Port Object */
00911     Status = NtCreatePort(&CsrSbApiPort,
00912                           &ObjectAttributes,
00913                           sizeof(SB_CONNECTION_INFO),
00914                           sizeof(SB_API_MSG),
00915                           32 * sizeof(SB_API_MSG));
00916     if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd);
00917 
00918     if (NT_SUCCESS(Status))
00919     {
00920         /* Create the Thread to handle the API Requests */
00921         Status = RtlCreateUserThread(NtCurrentProcess(),
00922                                      NULL,
00923                                      TRUE,
00924                                      0,
00925                                      0,
00926                                      0,
00927                                      (PVOID)CsrSbApiRequestThread,
00928                                      NULL,
00929                                      &hRequestThread,
00930                                      &ClientId);
00931         if (NT_SUCCESS(Status))
00932         {
00933             /* Add it as a Static Server Thread */
00934             CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread,
00935                                                                 &ClientId,
00936                                                                 0);
00937 
00938             /* Activate it */
00939             Status = NtResumeThread(hRequestThread, NULL);
00940         }
00941     }
00942 
00943     return Status;
00944 }
00945 
00946 /* PUBLIC FUNCTIONS ***********************************************************/
00947 
00948 NTSTATUS
00949 NTAPI
00950 CsrServerInitialization(IN ULONG ArgumentCount,
00951                         IN PCHAR Arguments[])
00952 {
00953     NTSTATUS Status = STATUS_SUCCESS;
00954     DPRINT("CSRSRV: %s called\n", __FUNCTION__);
00955 
00956     /* Create the Init Event */
00957     Status = NtCreateEvent(&CsrInitializationEvent,
00958                            EVENT_ALL_ACCESS,
00959                            NULL,
00960                            SynchronizationEvent,
00961                            FALSE);
00962     if (!NT_SUCCESS(Status))
00963     {
00964         DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
00965                 __FUNCTION__, Status);
00966         return Status;
00967     }
00968 
00969     /* Cache System Basic Information so we don't always request it */
00970     Status = NtQuerySystemInformation(SystemBasicInformation,
00971                                       &CsrNtSysInfo,
00972                                       sizeof(SYSTEM_BASIC_INFORMATION),
00973                                       NULL);
00974     if (!NT_SUCCESS(Status))
00975     {
00976         DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
00977                 __FUNCTION__, Status);
00978         return Status;
00979     }
00980 
00981     /* Save our Heap */
00982     CsrHeap = RtlGetProcessHeap();
00983 
00984     /* Set our Security Descriptor to protect the process */
00985     Status = CsrSetProcessSecurity();
00986     if (!NT_SUCCESS(Status))
00987     {
00988         DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
00989                 __FUNCTION__, Status);
00990         return Status;
00991     }
00992 
00993     /* Set up Session Support */
00994     Status = CsrInitializeNtSessionList();
00995     if (!NT_SUCCESS(Status))
00996     {
00997         DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
00998                 __FUNCTION__, Status);
00999         return Status;
01000     }
01001 
01002     /* Set up Process Support */
01003     Status = CsrInitializeProcessStructure();
01004     if (!NT_SUCCESS(Status))
01005     {
01006         DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
01007                 __FUNCTION__, Status);
01008         return Status;
01009     }
01010 
01011     /* Parse the command line */
01012     Status = CsrParseServerCommandLine(ArgumentCount, Arguments);
01013     if (!NT_SUCCESS(Status))
01014     {
01015         DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
01016                 __FUNCTION__, Status);
01017         return Status;
01018     }
01019 
01020     Status = CsrApiRegisterDefinitions(NativeDefinitions);
01021     if (!NT_SUCCESS(Status))
01022     {
01023         DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrApiRegisterDefinitions", Status);
01024     }
01025 
01026     /* Now initialize our API Port */
01027     Status = CsrApiPortInitialize();
01028     if (!NT_SUCCESS(Status))
01029     {
01030         DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
01031                 __FUNCTION__, Status);
01032         return Status;
01033     }
01034 
01035     /* Initialize Win32csr */
01036     Status = CsrLoadServerDll("win32csr", "Win32CsrInitialization", 2);
01037     if (!NT_SUCCESS(Status))
01038     {
01039         DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrLoadServerDll", Status);
01040     }
01041 
01042     /* Initialize the API Port for SM communication */
01043     Status = CsrSbApiPortInitialize();
01044     if (!NT_SUCCESS(Status))
01045     {
01046         DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
01047                 __FUNCTION__, Status);
01048         return Status;
01049     }
01050 
01051     /* We're all set! Connect to SM! */
01052     Status = SmConnectToSm(&CsrSbApiPortName,
01053                            CsrSbApiPort,
01054                            IMAGE_SUBSYSTEM_WINDOWS_GUI,
01055                            &CsrSmApiPort);
01056     if (!NT_SUCCESS(Status))
01057     {
01058         DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
01059                 __FUNCTION__, Status);
01060         return Status;
01061     }
01062 
01063     /* Finito! Signal the event */
01064     Status = NtSetEvent(CsrInitializationEvent, NULL);
01065     if (!NT_SUCCESS(Status))
01066     {
01067         DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
01068                 __FUNCTION__, Status);
01069         return Status;
01070     }
01071 
01072     /* Close the event handle now */
01073     NtClose(CsrInitializationEvent);
01074 
01075     /* Have us handle Hard Errors */
01076     Status = NtSetDefaultHardErrorPort(CsrApiPort);
01077     if (!NT_SUCCESS(Status))
01078     {
01079         DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
01080                 __FUNCTION__, Status);
01081         return Status;
01082     }
01083 
01084     /* Return status */
01085     return Status;
01086 }
01087 
01088 BOOL
01089 NTAPI
01090 DllMain(HANDLE hDll,
01091         DWORD dwReason,
01092         LPVOID lpReserved)
01093 {
01094     /* We don't do much */
01095     UNREFERENCED_PARAMETER(hDll);
01096     UNREFERENCED_PARAMETER(dwReason);
01097     UNREFERENCED_PARAMETER(lpReserved);
01098     return TRUE;
01099 }
01100 
01101 /* EOF */

Generated on Sun May 27 2012 04:23:32 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.