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

bootdata.c
Go to the documentation of this file.
00001 /* COPYRIGHT:       See COPYING in the top level directory
00002  * PROJECT:         ReactOS system libraries
00003  * PURPOSE:         Boot Data implementation
00004  * FILE:            lib/rtl/bootdata.c
00005  * PROGRAMMERS:
00006  */
00007 
00008 /* INCLUDES *****************************************************************/
00009 
00010 #include <rtl.h>
00011 
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 typedef struct _RTL_BSD_ITEM
00016 {
00017     ULONG Offset;
00018     ULONG Size;
00019 } RTL_BSD_ITEM, *PRTL_BSD_ITEM;
00020 
00021 /* FUNCTIONS *****************************************************************/
00022 
00023 static SID_IDENTIFIER_AUTHORITY LocalSystemAuthority = {SECURITY_NT_AUTHORITY};
00024 
00025 static RTL_BSD_ITEM BsdItemTable[6] = {{0, 4}, {4, 4,}, {8, 1}, {9, 1}, {10, 1}, {11, 1}};
00026 
00027 static NTSTATUS
00028 RtlpSysVolCreateSecurityDescriptor(OUT PISECURITY_DESCRIPTOR *SecurityDescriptor,
00029                                    OUT PSID *SystemSid)
00030 {
00031     PSECURITY_DESCRIPTOR AbsSD = NULL;
00032     PSID LocalSystemSid = NULL;
00033     PACL Dacl = NULL;
00034     ULONG DaclSize;
00035     NTSTATUS Status;
00036 
00037     /* create the local SYSTEM SID */
00038     Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
00039                                          1,
00040                                          SECURITY_LOCAL_SYSTEM_RID,
00041                                          0,
00042                                          0,
00043                                          0,
00044                                          0,
00045                                          0,
00046                                          0,
00047                                          0,
00048                                          &LocalSystemSid);
00049     if (!NT_SUCCESS(Status))
00050     {
00051         return Status;
00052     }
00053 
00054     /* allocate and initialize the security descriptor */
00055     AbsSD = RtlpAllocateMemory(sizeof(SECURITY_DESCRIPTOR),
00056                                'dSeS');
00057     if (AbsSD == NULL)
00058     {
00059         Status = STATUS_NO_MEMORY;
00060         goto Cleanup;
00061     }
00062 
00063     Status = RtlCreateSecurityDescriptor(AbsSD,
00064                                          SECURITY_DESCRIPTOR_REVISION);
00065     if (!NT_SUCCESS(Status))
00066     {
00067         goto Cleanup;
00068     }
00069 
00070     /* allocate and create the DACL */
00071     DaclSize = sizeof(ACL) + sizeof(ACE) +
00072                RtlLengthSid(LocalSystemSid);
00073     Dacl = RtlpAllocateMemory(DaclSize,
00074                               'cAeS');
00075     if (Dacl == NULL)
00076     {
00077         Status = STATUS_NO_MEMORY;
00078         goto Cleanup;
00079     }
00080 
00081     Status = RtlCreateAcl(Dacl,
00082                           DaclSize,
00083                           ACL_REVISION);
00084     if (!NT_SUCCESS(Status))
00085     {
00086         goto Cleanup;
00087     }
00088 
00089     Status = RtlAddAccessAllowedAceEx(Dacl,
00090                                       ACL_REVISION,
00091                                       OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
00092                                       STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
00093                                       LocalSystemSid);
00094     if (!NT_SUCCESS(Status))
00095     {
00096         goto Cleanup;
00097     }
00098 
00099     /* set the DACL in the security descriptor */
00100     Status = RtlSetDaclSecurityDescriptor(AbsSD,
00101                                           TRUE,
00102                                           Dacl,
00103                                           FALSE);
00104 
00105     /* all done */
00106     if (NT_SUCCESS(Status))
00107     {
00108         *SecurityDescriptor = AbsSD;
00109         *SystemSid = LocalSystemSid;
00110     }
00111     else
00112     {
00113 Cleanup:
00114         if (LocalSystemSid != NULL)
00115         {
00116             RtlFreeSid(LocalSystemSid);
00117         }
00118 
00119         if (Dacl != NULL)
00120         {
00121             RtlpFreeMemory(Dacl,
00122                            'cAeS');
00123         }
00124 
00125         if (AbsSD != NULL)
00126         {
00127             RtlpFreeMemory(AbsSD,
00128                            'dSeS');
00129         }
00130     }
00131 
00132     return Status;
00133 }
00134 
00135 static NTSTATUS
00136 RtlpSysVolCheckOwnerAndSecurity(IN HANDLE DirectoryHandle,
00137                                 IN PISECURITY_DESCRIPTOR SecurityDescriptor)
00138 {
00139     PSECURITY_DESCRIPTOR RelSD = NULL;
00140     PSECURITY_DESCRIPTOR NewRelSD = NULL;
00141     PSECURITY_DESCRIPTOR AbsSD = NULL;
00142 #ifdef _WIN64
00143     BOOLEAN AbsSDAllocated = FALSE;
00144 #endif
00145     PSID AdminSid = NULL;
00146     PSID LocalSystemSid = NULL;
00147     ULONG DescriptorSize;
00148     ULONG AbsSDSize, RelSDSize = 0;
00149     PACL Dacl;
00150     BOOLEAN DaclPresent, DaclDefaulted;
00151     PSID OwnerSid;
00152     BOOLEAN OwnerDefaulted;
00153     ULONG AceIndex;
00154     PACE Ace = NULL;
00155     NTSTATUS Status;
00156 
00157     /* find out how much memory we need to allocate for the self-relative
00158        descriptor we're querying */
00159     Status = ZwQuerySecurityObject(DirectoryHandle,
00160                                    OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
00161                                    NULL,
00162                                    0,
00163                                    &DescriptorSize);
00164     if (Status != STATUS_BUFFER_TOO_SMALL)
00165     {
00166         /* looks like the FS doesn't support security... return success */
00167         Status = STATUS_SUCCESS;
00168         goto Cleanup;
00169     }
00170 
00171     /* allocate enough memory for the security descriptor */
00172     RelSD = RtlpAllocateMemory(DescriptorSize,
00173                                'dSeS');
00174     if (RelSD == NULL)
00175     {
00176         Status = STATUS_NO_MEMORY;
00177         goto Cleanup;
00178     }
00179 
00180     /* query the self-relative security descriptor */
00181     Status = ZwQuerySecurityObject(DirectoryHandle,
00182                                    OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
00183                                    RelSD,
00184                                    DescriptorSize,
00185                                    &DescriptorSize);
00186     if (!NT_SUCCESS(Status))
00187     {
00188         /* FIXME - handle the case where someone else modified the owner and/or
00189                    DACL while we allocated memory. But that should be *very*
00190                    unlikely.... */
00191         goto Cleanup;
00192     }
00193 
00194     /* query the owner and DACL from the descriptor */
00195     Status = RtlGetOwnerSecurityDescriptor(RelSD,
00196                                            &OwnerSid,
00197                                            &OwnerDefaulted);
00198     if (!NT_SUCCESS(Status))
00199     {
00200         goto Cleanup;
00201     }
00202 
00203     Status = RtlGetDaclSecurityDescriptor(RelSD,
00204                                           &DaclPresent,
00205                                           &Dacl,
00206                                           &DaclDefaulted);
00207     if (!NT_SUCCESS(Status))
00208     {
00209         goto Cleanup;
00210     }
00211 
00212     /* create the Administrators SID */
00213     Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
00214                                          2,
00215                                          SECURITY_BUILTIN_DOMAIN_RID,
00216                                          DOMAIN_ALIAS_RID_ADMINS,
00217                                          0,
00218                                          0,
00219                                          0,
00220                                          0,
00221                                          0,
00222                                          0,
00223                                          &AdminSid);
00224     if (!NT_SUCCESS(Status))
00225     {
00226         goto Cleanup;
00227     }
00228 
00229     /* create the local SYSTEM SID */
00230     Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
00231                                          1,
00232                                          SECURITY_LOCAL_SYSTEM_RID,
00233                                          0,
00234                                          0,
00235                                          0,
00236                                          0,
00237                                          0,
00238                                          0,
00239                                          0,
00240                                          &LocalSystemSid);
00241     if (!NT_SUCCESS(Status))
00242     {
00243         goto Cleanup;
00244     }
00245 
00246     /* check if the Administrators are the owner and at least a not-NULL DACL
00247        is present */
00248     if (OwnerSid != NULL &&
00249         RtlEqualSid(OwnerSid,
00250                     AdminSid) &&
00251         DaclPresent && Dacl != NULL)
00252     {
00253         /* check the DACL for an Allowed ACE for the SYSTEM account */
00254         AceIndex = 0;
00255         do
00256         {
00257             Status = RtlGetAce(Dacl,
00258                                AceIndex++,
00259                                (PVOID*)&Ace);
00260             if (!NT_SUCCESS(Status))
00261             {
00262                 Ace = NULL;
00263             }
00264             else if (Ace != NULL && Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
00265             {
00266                 /* check if the the ACE is a set of allowed permissions for the
00267                    local SYSTEM account */
00268                 if (RtlEqualSid((PSID)(Ace + 1),
00269                                 LocalSystemSid))
00270                 {
00271                     /* check if the ACE is inherited by noncontainer and
00272                        container objects, if not attempt to change that */
00273                     if (!(Ace->Header.AceFlags & OBJECT_INHERIT_ACE) ||
00274                         !(Ace->Header.AceFlags & CONTAINER_INHERIT_ACE))
00275                     {
00276                         Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
00277                         Status = ZwSetSecurityObject(DirectoryHandle,
00278                                                      DACL_SECURITY_INFORMATION,
00279                                                      RelSD);
00280                     }
00281                     else
00282                     {
00283                         /* all done, we have access */
00284                         Status = STATUS_SUCCESS;
00285                     }
00286 
00287                     goto Cleanup;
00288                 }
00289             }
00290         } while (Ace != NULL);
00291     }
00292 
00293     AbsSDSize = DescriptorSize;
00294 
00295     /* because we need to change any existing data we need to convert it to
00296        an absolute security descriptor first */
00297     Status = RtlSelfRelativeToAbsoluteSD2(RelSD,
00298                                           &AbsSDSize);
00299 #ifdef _WIN64
00300     if (Status == STATUS_BUFFER_TOO_SMALL)
00301     {
00302         /* this error code can only be returned on 64 bit builds because
00303            the size of an absolute security descriptor is greater than the
00304            size of a self-relative security descriptor */
00305         ASSERT(AbsSDSize > DescriptorSize);
00306 
00307         AbsSD = RtlpAllocateMemory(DescriptorSize,
00308                                    'dSeS');
00309         if (AbsSD == NULL)
00310         {
00311             Status = STATUS_NO_MEMORY;
00312             goto Cleanup;
00313         }
00314 
00315         AbsSDAllocated = TRUE;
00316 
00317         /* make a raw copy of the self-relative descriptor */
00318         RtlCopyMemory(AbsSD,
00319                       RelSD,
00320                       DescriptorSize);
00321 
00322         /* finally convert it */
00323         Status = RtlSelfRelativeToAbsoluteSD2(AbsSD,
00324                                               &AbsSDSize);
00325     }
00326     else
00327 #endif
00328     {
00329         AbsSD = RelSD;
00330     }
00331 
00332     if (!NT_SUCCESS(Status))
00333     {
00334         goto Cleanup;
00335     }
00336 
00337     /* set the owner SID */
00338     Status = RtlSetOwnerSecurityDescriptor(AbsSD,
00339                                            AdminSid,
00340                                            FALSE);
00341     if (!NT_SUCCESS(Status))
00342     {
00343         goto Cleanup;
00344     }
00345 
00346     /* set the DACL in the security descriptor */
00347     Status = RtlSetDaclSecurityDescriptor(AbsSD,
00348                                           TRUE,
00349                                           SecurityDescriptor->Dacl,
00350                                           FALSE);
00351     if (!NT_SUCCESS(Status))
00352     {
00353         goto Cleanup;
00354     }
00355 
00356     /* convert it back to a self-relative descriptor, find out how much
00357        memory we need */
00358     Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
00359                                          NULL,
00360                                          &RelSDSize);
00361     if (Status != STATUS_BUFFER_TOO_SMALL)
00362     {
00363         goto Cleanup;
00364     }
00365 
00366     /* allocate enough memory for the new self-relative descriptor */
00367     NewRelSD = RtlpAllocateMemory(RelSDSize,
00368                                   'dSeS');
00369     if (NewRelSD == NULL)
00370     {
00371         Status = STATUS_NO_MEMORY;
00372         goto Cleanup;
00373     }
00374 
00375     /* convert the security descriptor to self-relative format */
00376     Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
00377                                          NewRelSD,
00378                                          &RelSDSize);
00379     if (Status == STATUS_BUFFER_TOO_SMALL)
00380     {
00381         goto Cleanup;
00382     }
00383 
00384     /* finally attempt to change the security information */
00385     Status = ZwSetSecurityObject(DirectoryHandle,
00386                                  OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
00387                                  NewRelSD);
00388 
00389 Cleanup:
00390     if (AdminSid != NULL)
00391     {
00392         RtlFreeSid(AdminSid);
00393     }
00394 
00395     if (LocalSystemSid != NULL)
00396     {
00397         RtlFreeSid(LocalSystemSid);
00398     }
00399 
00400     if (RelSD != NULL)
00401     {
00402         RtlpFreeMemory(RelSD,
00403                        'dSeS');
00404     }
00405 
00406     if (NewRelSD != NULL)
00407     {
00408         RtlpFreeMemory(NewRelSD,
00409                        'dSeS');
00410     }
00411 
00412 #ifdef _WIN64
00413     if (AbsSDAllocated)
00414     {
00415         RtlpFreeMemory(AbsSD,
00416                        'dSeS');
00417     }
00418 #endif
00419 
00420     return Status;
00421 }
00422 
00423 static NTSTATUS
00424 RtlpSysVolTakeOwnership(IN PUNICODE_STRING DirectoryPath,
00425                         IN PSECURITY_DESCRIPTOR SecurityDescriptor)
00426 {
00427     TOKEN_PRIVILEGES TokenPrivileges;
00428     OBJECT_ATTRIBUTES ObjectAttributes;
00429     SECURITY_DESCRIPTOR AbsSD;
00430     PSID AdminSid = NULL;
00431     IO_STATUS_BLOCK IoStatusBlock;
00432     BOOLEAN TokenEnabled = FALSE;
00433     HANDLE hToken = NULL;
00434     HANDLE hDirectory = NULL;
00435     NTSTATUS Status;
00436 
00437     Status = ZwOpenProcessToken(NtCurrentProcess(),
00438                                 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
00439                                 &hToken);
00440     if (!NT_SUCCESS(Status))
00441     {
00442         goto Cleanup;
00443     }
00444 
00445     /* attempt to enable the SE_TAKE_OWNERSHIP_PRIVILEGE privilege */
00446     TokenPrivileges.PrivilegeCount = 1;
00447     TokenPrivileges.Privileges[0].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE;
00448     TokenPrivileges.Privileges[0].Luid.HighPart = 0;
00449     TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
00450     Status = ZwAdjustPrivilegesToken(hToken,
00451                                      FALSE,
00452                                      &TokenPrivileges,
00453                                      sizeof(TokenPrivileges),
00454                                      &TokenPrivileges,
00455                                      NULL);
00456     if (!NT_SUCCESS(Status))
00457     {
00458         goto Cleanup;
00459     }
00460     TokenEnabled = (TokenPrivileges.PrivilegeCount != 0);
00461 
00462     /* open the directory */
00463     InitializeObjectAttributes(&ObjectAttributes,
00464                                DirectoryPath,
00465                                0,
00466                                NULL,
00467                                SecurityDescriptor);
00468 
00469     Status = ZwOpenFile(&hDirectory,
00470                         SYNCHRONIZE | WRITE_OWNER,
00471                         &ObjectAttributes,
00472                         &IoStatusBlock,
00473                         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
00474                         FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
00475     if (!NT_SUCCESS(Status))
00476     {
00477         goto Cleanup;
00478     }
00479 
00480     /* create the Administrators SID */
00481     Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
00482                                          2,
00483                                          SECURITY_BUILTIN_DOMAIN_RID,
00484                                          DOMAIN_ALIAS_RID_ADMINS,
00485                                          0,
00486                                          0,
00487                                          0,
00488                                          0,
00489                                          0,
00490                                          0,
00491                                          &AdminSid);
00492     if (!NT_SUCCESS(Status))
00493     {
00494         goto Cleanup;
00495     }
00496 
00497     /* create the security descriptor */
00498     Status = RtlCreateSecurityDescriptor(&AbsSD,
00499                                          SECURITY_DESCRIPTOR_REVISION);
00500     if (!NT_SUCCESS(Status))
00501     {
00502         goto Cleanup;
00503     }
00504 
00505     Status = RtlSetOwnerSecurityDescriptor(&AbsSD,
00506                                            AdminSid,
00507                                            FALSE);
00508     if (!NT_SUCCESS(Status))
00509     {
00510         goto Cleanup;
00511     }
00512 
00513     /* attempt to take ownership */
00514     Status = ZwSetSecurityObject(hDirectory,
00515                                  OWNER_SECURITY_INFORMATION,
00516                                  &AbsSD);
00517 
00518 Cleanup:
00519     if (TokenEnabled)
00520     {
00521         ZwAdjustPrivilegesToken(hToken,
00522                                 FALSE,
00523                                 &TokenPrivileges,
00524                                 0,
00525                                 NULL,
00526                                 NULL);
00527     }
00528 
00529     if (AdminSid != NULL)
00530     {
00531         RtlFreeSid(AdminSid);
00532     }
00533 
00534     if (hDirectory != NULL)
00535     {
00536         ZwClose(hDirectory);
00537     }
00538 
00539     if (hToken != NULL)
00540     {
00541         ZwClose(hToken);
00542     }
00543 
00544     return Status;
00545 }
00546 
00547 /*
00548 * @implemented
00549 */
00550 NTSTATUS
00551 NTAPI
00552 RtlCreateSystemVolumeInformationFolder(IN PUNICODE_STRING VolumeRootPath)
00553 {
00554     OBJECT_ATTRIBUTES ObjectAttributes;
00555     IO_STATUS_BLOCK IoStatusBlock;
00556     HANDLE hDirectory;
00557     UNICODE_STRING DirectoryName, NewPath;
00558     ULONG PathLen;
00559     PISECURITY_DESCRIPTOR SecurityDescriptor = NULL;
00560     PSID SystemSid = NULL;
00561     BOOLEAN AddSep = FALSE;
00562     NTSTATUS Status;
00563 
00564     PAGED_CODE_RTL();
00565 
00566     RtlInitUnicodeString(&DirectoryName,
00567                          L"System Volume Information");
00568 
00569     PathLen = VolumeRootPath->Length + DirectoryName.Length;
00570 
00571     /* make sure we don't overflow while appending the strings */
00572     if (PathLen > 0xFFFC)
00573     {
00574         return STATUS_INVALID_PARAMETER;
00575     }
00576 
00577     if (VolumeRootPath->Buffer[(VolumeRootPath->Length / sizeof(WCHAR)) - 1] != L'\\')
00578     {
00579         AddSep = TRUE;
00580         PathLen += sizeof(WCHAR);
00581     }
00582 
00583     /* allocate the new string */
00584     NewPath.MaximumLength = (USHORT)PathLen + sizeof(WCHAR);
00585     NewPath.Buffer = RtlpAllocateStringMemory(NewPath.MaximumLength,
00586                                               TAG_USTR);
00587     if (NewPath.Buffer == NULL)
00588     {
00589         return STATUS_INSUFFICIENT_RESOURCES;
00590     }
00591 
00592     /* create the new path string */
00593     NewPath.Length = VolumeRootPath->Length;
00594     RtlCopyMemory(NewPath.Buffer,
00595                   VolumeRootPath->Buffer,
00596                   NewPath.Length);
00597     if (AddSep)
00598     {
00599         NewPath.Buffer[NewPath.Length / sizeof(WCHAR)] = L'\\';
00600         NewPath.Length += sizeof(WCHAR);
00601     }
00602     RtlCopyMemory(NewPath.Buffer + (NewPath.Length / sizeof(WCHAR)),
00603                   DirectoryName.Buffer,
00604                   DirectoryName.Length);
00605     NewPath.Length += DirectoryName.Length;
00606     NewPath.Buffer[NewPath.Length / sizeof(WCHAR)] = L'\0';
00607 
00608     ASSERT(NewPath.Length == PathLen);
00609     ASSERT(NewPath.Length == NewPath.MaximumLength - sizeof(WCHAR));
00610 
00611     /* create the security descriptor for the new directory */
00612     Status = RtlpSysVolCreateSecurityDescriptor(&SecurityDescriptor,
00613                                                 &SystemSid);
00614     if (NT_SUCCESS(Status))
00615     {
00616         /* create or open the directory */
00617         InitializeObjectAttributes(&ObjectAttributes,
00618                                    &NewPath,
00619                                    0,
00620                                    NULL,
00621                                    SecurityDescriptor);
00622 
00623         Status = ZwCreateFile(&hDirectory,
00624                               SYNCHRONIZE | WRITE_OWNER | WRITE_DAC | READ_CONTROL,
00625                               &ObjectAttributes,
00626                               &IoStatusBlock,
00627                               NULL,
00628                               FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
00629                               FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
00630                               FILE_OPEN_IF,
00631                               FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
00632                               NULL,
00633                               0);
00634         if (!NT_SUCCESS(Status))
00635         {
00636             Status = RtlpSysVolTakeOwnership(&NewPath,
00637                                              SecurityDescriptor);
00638 
00639             if (NT_SUCCESS(Status))
00640             {
00641                 /* successfully took ownership, attempt to open it */
00642                 Status = ZwCreateFile(&hDirectory,
00643                                       SYNCHRONIZE | WRITE_OWNER | WRITE_DAC | READ_CONTROL,
00644                                       &ObjectAttributes,
00645                                       &IoStatusBlock,
00646                                       NULL,
00647                                       FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
00648                                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
00649                                       FILE_OPEN_IF,
00650                                       FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
00651                                       NULL,
00652                                       0);
00653             }
00654         }
00655 
00656         if (NT_SUCCESS(Status))
00657         {
00658             /* check security now and adjust it if neccessary */
00659             Status = RtlpSysVolCheckOwnerAndSecurity(hDirectory,
00660                                                      SecurityDescriptor);
00661             ZwClose(hDirectory);
00662         }
00663 
00664         /* free allocated memory */
00665         ASSERT(SecurityDescriptor != NULL);
00666         ASSERT(SecurityDescriptor->Dacl != NULL);
00667 
00668         RtlpFreeMemory(SecurityDescriptor->Dacl,
00669                        'cAeS');
00670         RtlpFreeMemory(SecurityDescriptor,
00671                        'dSeS');
00672 
00673         RtlFreeSid(SystemSid);
00674     }
00675 
00676     RtlpFreeStringMemory(NewPath.Buffer,
00677                          TAG_USTR);
00678     return Status;
00679 }
00680 
00681 /*
00682 * @implemented
00683 */
00684 NTSTATUS
00685 NTAPI
00686 RtlCreateBootStatusDataFile(VOID)
00687 {
00688     OBJECT_ATTRIBUTES ObjectAttributes;
00689     IO_STATUS_BLOCK IoStatusBlock;
00690     LARGE_INTEGER AllocationSize;
00691     LARGE_INTEGER ByteOffset;
00692     UNICODE_STRING FileName;
00693     HANDLE FileHandle;
00694     NTSTATUS Status;
00695 
00696     /* Initialize the file name */
00697     RtlInitUnicodeString(&FileName,
00698                          L"\\SystemRoot\\bootstat.dat");
00699 
00700     /* Initialize the object attributes */
00701     InitializeObjectAttributes(&ObjectAttributes,
00702                                &FileName,
00703                                OBJ_CASE_INSENSITIVE,
00704                                NULL,
00705                                NULL);
00706 
00707     AllocationSize.QuadPart = 0x800;
00708 
00709     /* Create the boot status data file */
00710     Status = ZwCreateFile(&FileHandle,
00711                           FILE_GENERIC_READ | FILE_GENERIC_WRITE,
00712                           &ObjectAttributes,
00713                           &IoStatusBlock,
00714                           NULL, //&AllocationSize,
00715                           FILE_ATTRIBUTE_SYSTEM,
00716                           0,
00717                           FILE_CREATE,
00718                           FILE_SYNCHRONOUS_IO_NONALERT,
00719                           NULL,
00720                           0);
00721     if (NT_SUCCESS(Status))
00722     {
00723         // FIXME: Initialize the buffer in a better way.
00724         UCHAR Buffer[12] = {0xC,0,0,0, 1,0,0,0, 1, 0x1e, 1, 0};
00725 
00726         ByteOffset.QuadPart = 0;
00727         Status = ZwWriteFile(FileHandle,
00728                              NULL,
00729                              NULL,
00730                              NULL,
00731                              &IoStatusBlock,
00732                              &Buffer,
00733                              12, //BufferSize,
00734                              &ByteOffset,
00735                              NULL);
00736     }
00737 
00738     /* Close the file */
00739     ZwClose(FileHandle);
00740 
00741     return Status;
00742 }
00743 
00744 /*
00745 * @implemented
00746 */
00747 NTSTATUS
00748 NTAPI
00749 RtlGetSetBootStatusData(IN HANDLE FileHandle,
00750                         IN BOOLEAN WriteMode,
00751                         IN RTL_BSD_ITEM_TYPE DataClass,
00752                         IN PVOID Buffer,
00753                         IN ULONG BufferSize,
00754                         OUT PULONG ReturnLength)
00755 {
00756     IO_STATUS_BLOCK IoStatusBlock;
00757     LARGE_INTEGER ByteOffset;
00758     NTSTATUS Status;
00759 
00760     DPRINT("RtlGetSetBootStatusData (%p %u %u %p %lu %p)\n",
00761            FileHandle, WriteMode, DataClass, Buffer, BufferSize, ReturnLength);
00762 
00763     if (DataClass >= RtlBsdItemMax)
00764         return STATUS_INVALID_PARAMETER;
00765 
00766     if (BufferSize > BsdItemTable[DataClass].Size)
00767         return STATUS_BUFFER_TOO_SMALL;
00768 
00769     ByteOffset.HighPart = 0;
00770     ByteOffset.LowPart = BsdItemTable[DataClass].Offset;
00771 
00772     if (WriteMode)
00773     {
00774         Status = ZwReadFile(FileHandle,
00775                             NULL,
00776                             NULL,
00777                             NULL,
00778                             &IoStatusBlock,
00779                             Buffer,
00780                             BufferSize,
00781                             &ByteOffset,
00782                             NULL);
00783     }
00784     else
00785     {
00786         Status = ZwWriteFile(FileHandle,
00787                              NULL,
00788                              NULL,
00789                              NULL,
00790                              &IoStatusBlock,
00791                              Buffer,
00792                              BufferSize,
00793                              &ByteOffset,
00794                              NULL);
00795     }
00796 
00797     if (NT_SUCCESS(Status))
00798     {
00799         if (ReturnLength)
00800             *ReturnLength = BsdItemTable[DataClass].Size;
00801     }
00802 
00803     return Status;
00804 }
00805 
00806 /*
00807 * @implemented
00808 */
00809 NTSTATUS
00810 NTAPI
00811 RtlLockBootStatusData(OUT PHANDLE FileHandle)
00812 {
00813     OBJECT_ATTRIBUTES ObjectAttributes;
00814     IO_STATUS_BLOCK IoStatusBlock;
00815     UNICODE_STRING FileName;
00816     HANDLE LocalFileHandle;
00817     NTSTATUS Status;
00818 
00819     /* Intialize the file handle */
00820     *FileHandle = NULL;
00821 
00822     /* Initialize the file name */
00823     RtlInitUnicodeString(&FileName,
00824                          L"\\SystemRoot\\bootstat.dat");
00825 
00826     /* Initialize the object attributes */
00827     InitializeObjectAttributes(&ObjectAttributes,
00828                                &FileName,
00829                                0,
00830                                NULL,
00831                                NULL);
00832 
00833     /* Open the boot status data file */
00834     Status = ZwOpenFile(&LocalFileHandle,
00835                         FILE_ALL_ACCESS,
00836                         &ObjectAttributes,
00837                         &IoStatusBlock,
00838                         0,
00839                         FILE_SYNCHRONOUS_IO_NONALERT);
00840     if (NT_SUCCESS(Status))
00841     {
00842         /* Return the file handle */
00843         *FileHandle = LocalFileHandle;
00844     }
00845 
00846     return Status;
00847 }
00848 
00849 /*
00850 * @implemented
00851 */
00852 NTSTATUS
00853 NTAPI
00854 RtlUnlockBootStatusData(IN HANDLE FileHandle)
00855 {
00856     IO_STATUS_BLOCK IoStatusBlock;
00857 
00858     /* Flush the file and close it */
00859     ZwFlushBuffersFile(FileHandle,
00860                        &IoStatusBlock);
00861 
00862     return ZwClose(FileHandle);
00863 }
00864 
00865 /* EOF */

Generated on Sun May 27 2012 04:27:12 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.