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