https://git.reactos.org/?p=reactos.git;a=commitdiff;h=16e0cca7e13efe9a77905b846a8f92619ff99ec5
commit 16e0cca7e13efe9a77905b846a8f92619ff99ec5 Author: Alex Ionescu <aione...@gmail.com> AuthorDate: Sun Feb 4 09:33:32 2018 -0800 Commit: Alex Ionescu <aione...@gmail.com> CommitDate: Sun Feb 4 09:33:32 2018 -0800 [RTL]: Document and flesh out Boot Status Data (BSD) API/Structures [NDK]: Document latest RTL_BSD_DATA as of RS3 based on ext.dll WinDBG extension "!blackboxbsd" which outputs the entire structure field by field :). [NDK]: Update RTL_BSD_ITEM_TYPE thanks to ole32 symbols [RTL]: Move system volume APIs to sysvol.c [RTL]: Fill out BsdItemTable based on actual field offsets/sizes and not hardcoded magic numbers which we won't ask where they came from. [RTL]: Make RtlCreateBootStatusDataFile use an appropriate structure for initializing the buffer instead of "UCHAR Buffer[12] = {0xC,0,0,0, 1,0,0,0, 1, 0x1e, 1, 0};" which appears like magic knowledge. [RTL]: Rename "WriteMode" to "Read" in RtlGetSetBootStatusData since it's much less confusing. [RTL]: Some formatting fixes, SAL updates. --- sdk/include/ndk/rtltypes.h | 100 ++++- sdk/lib/rtl/CMakeLists.txt | 1 + sdk/lib/rtl/bootdata.c | 820 +++++------------------------------ sdk/lib/rtl/{bootdata.c => sysvol.c} | 194 --------- 4 files changed, 213 insertions(+), 902 deletions(-) diff --git a/sdk/include/ndk/rtltypes.h b/sdk/include/ndk/rtltypes.h index 0abde3e0c0..1371f4c86f 100644 --- a/sdk/include/ndk/rtltypes.h +++ b/sdk/include/ndk/rtltypes.h @@ -414,9 +414,6 @@ C_ASSERT(FIELD_OFFSET(LARGE_INTEGER, LowPart) == 0); #define RTL_CONSTANT_LARGE_INTEGER(quad_part) { { (quad_part), (quad_part)>>32 } } #define RTL_MAKE_LARGE_INTEGER(low_part, high_part) { { (low_part), (high_part) } } - -#ifdef NTOS_MODE_USER - // // Boot Status Data Field Types // @@ -428,9 +425,20 @@ typedef enum _RTL_BSD_ITEM_TYPE RtlBsdItemAabTimeout, RtlBsdItemBootGood, RtlBsdItemBootShutdown, + RtlBsdSleepInProgress, + RtlBsdPowerTransition, + RtlBsdItemBootAttemptCount, + RtlBsdItemBootCheckpoint, + RtlBsdItemBootId, + RtlBsdItemShutdownBootId, + RtlBsdItemReportedAbnormalShutdownBootId, + RtlBsdItemErrorInfo, + RtlBsdItemPowerButtonPressInfo, + RtlBsdItemChecksum, RtlBsdItemMax } RTL_BSD_ITEM_TYPE, *PRTL_BSD_ITEM_TYPE; +#ifdef NTOS_MODE_USER // // Table and Compare result types // @@ -1238,6 +1246,92 @@ typedef struct _RTL_HANDLE_TABLE PRTL_HANDLE_TABLE_ENTRY MaxReservedHandles; } RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE; +// +// RTL Boot Status Data Item +// +typedef struct _RTL_BSD_ITEM +{ + RTL_BSD_ITEM_TYPE Type; + PVOID DataBuffer; + ULONG DataLength; +} RTL_BSD_ITEM, *PRTL_BSD_ITEM; + +// +// Data Sub-Structures for "bootstat.dat" RTL Data File +// +typedef struct _RTL_BSD_DATA_POWER_TRANSITION +{ + LARGE_INTEGER PowerButtonTimestamp; + struct + { + UCHAR SystemRunning : 1; + UCHAR ConnectedStandbyInProgress : 1; + UCHAR UserShutdownInProgress : 1; + UCHAR SystemShutdownInProgress : 1; + UCHAR SleepInProgress : 4; + } Flags; + UCHAR ConnectedStandbyScenarioInstanceId; + UCHAR ConnectedStandbyEntryReason; + UCHAR ConnectedStandbyExitReason; + USHORT SystemSleepTransitionCount; + LARGE_INTEGER LastReferenceTime; + ULONG LastReferenceTimeChecksum; + ULONG LastUpdateBootId; +} RTL_BSD_DATA_POWER_TRANSITION, *PRTL_BSD_DATA_POWER_TRANSITION; + +typedef struct _RTL_BSD_DATA_ERROR_INFO +{ + ULONG BootId; + ULONG RepeatCount; + ULONG OtherErrorCount; + ULONG Code; + ULONG OtherErrorCount2; +} RTL_BSD_DATA_ERROR_INFO, *PRTL_BSD_DATA_ERROR_INFO; + +typedef struct _RTL_BSD_POWER_BUTTON_PRESS_INFO +{ + LARGE_INTEGER LastPressTime; + ULONG CumulativePressCount; + USHORT LastPressBootId; + UCHAR LastPowerWatchdogStage; + struct + { + UCHAR WatchdogArmed : 1; + UCHAR ShutdownInProgress : 1; + } Flags; + LARGE_INTEGER LastReleaseTime; + ULONG CumulativeReleaseCount; + USHORT LastReleaseBootId; + USHORT ErrorCount; + UCHAR CurrentConnectedStandbyPhase; + ULONG TransitionLatestCheckpointId; + ULONG TransitionLatestCheckpointType; + ULONG TransitionLatestCheckpointSequenceNumber; +} RTL_BSD_POWER_BUTTON_PRESS_INFO, *PRTL_BSD_POWER_BUTTON_PRESS_INFO; + +// +// Main Structure for "bootstat.dat" RTL Data File +// +typedef struct _RTL_BSD_DATA +{ + ULONG Version; // RtlBsdItemVersionNumber + ULONG ProductType; // RtlBsdItemProductType + BOOLEAN AabEnabled; // RtlBsdItemAabEnabled + UCHAR AabTimeout; // RtlBsdItemAabTimeout + BOOLEAN LastBootSucceeded; // RtlBsdItemBootGood + BOOLEAN LastBootShutdown; // RtlBsdItemBootShutdown + BOOLEAN SleepInProgress; // RtlBsdSleepInProgress + RTL_BSD_DATA_POWER_TRANSITION PowerTransition; // RtlBsdPowerTransition + UCHAR BootAttemptCount; // RtlBsdItemBootAttemptCount + UCHAR LastBootCheckpoint; // RtlBsdItemBootCheckpoint + UCHAR Checksum; // RtlBsdItemChecksum + ULONG LastBootId; // RtlBsdItemBootId + ULONG LastSuccessfulShutdownBootId; // RtlBsdItemShutdownBootId + ULONG LastReportedAbnormalShutdownBootId; // RtlBsdItemReportedAbnormalShutdownBootId + RTL_BSD_DATA_ERROR_INFO ErrorInfo; // RtlBsdItemErrorInfo + RTL_BSD_POWER_BUTTON_PRESS_INFO PowerButtonPressInfo; // RtlBsdItemPowerButtonPressInfo +} RTL_BSD_DATA, *PRTL_BSD_DATA; + #ifdef NTOS_MODE_USER // // Exception Record diff --git a/sdk/lib/rtl/CMakeLists.txt b/sdk/lib/rtl/CMakeLists.txt index 7279a2e2ea..573e4c0802 100644 --- a/sdk/lib/rtl/CMakeLists.txt +++ b/sdk/lib/rtl/CMakeLists.txt @@ -56,6 +56,7 @@ list(APPEND SOURCE slist.c sid.c splaytree.c + sysvol.c thread.c time.c timezone.c diff --git a/sdk/lib/rtl/bootdata.c b/sdk/lib/rtl/bootdata.c index 77d367426d..b674eb2545 100644 --- a/sdk/lib/rtl/bootdata.c +++ b/sdk/lib/rtl/bootdata.c @@ -1,715 +1,118 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * PURPOSE: Boot Data implementation + * PROJECT: ReactOS Runtime Library + * LICENSE: See COPYING in the top level directory * FILE: lib/rtl/bootdata.c - * PROGRAMMERS: + * PURPOSE: Boot Status Data Implementation + * PROGRAMMERS: Alex Ionescu (alex.ione...@reactos.org) + * Eric Kohl */ /* INCLUDES *****************************************************************/ #include <rtl.h> - #define NDEBUG #include <debug.h> -typedef struct _RTL_BSD_ITEM +typedef struct _RTL_BSD_ITEM_TABLE_ENTRY { - ULONG Offset; - ULONG Size; -} RTL_BSD_ITEM, *PRTL_BSD_ITEM; + UCHAR Offset; + UCHAR Size; +} RTL_BSD_ITEM_TABLE_ENTRY; /* FUNCTIONS *****************************************************************/ -static SID_IDENTIFIER_AUTHORITY LocalSystemAuthority = {SECURITY_NT_AUTHORITY}; - -static RTL_BSD_ITEM BsdItemTable[6] = {{0, 4}, {4, 4,}, {8, 1}, {9, 1}, {10, 1}, {11, 1}}; - -static NTSTATUS -RtlpSysVolCreateSecurityDescriptor(OUT PISECURITY_DESCRIPTOR *SecurityDescriptor, - OUT PSID *SystemSid) -{ - PSECURITY_DESCRIPTOR AbsSD = NULL; - PSID LocalSystemSid = NULL; - PACL Dacl = NULL; - ULONG DaclSize; - NTSTATUS Status; - - /* create the local SYSTEM SID */ - Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, - 1, - SECURITY_LOCAL_SYSTEM_RID, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - &LocalSystemSid); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - /* allocate and initialize the security descriptor */ - AbsSD = RtlpAllocateMemory(sizeof(SECURITY_DESCRIPTOR), - 'dSeS'); - if (AbsSD == NULL) - { - Status = STATUS_NO_MEMORY; - goto Cleanup; - } - - Status = RtlCreateSecurityDescriptor(AbsSD, - SECURITY_DESCRIPTOR_REVISION); - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - /* allocate and create the DACL */ - DaclSize = sizeof(ACL) + sizeof(ACE) + - RtlLengthSid(LocalSystemSid); - Dacl = RtlpAllocateMemory(DaclSize, - 'cAeS'); - if (Dacl == NULL) - { - Status = STATUS_NO_MEMORY; - goto Cleanup; - } - - Status = RtlCreateAcl(Dacl, - DaclSize, - ACL_REVISION); - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - Status = RtlAddAccessAllowedAceEx(Dacl, - ACL_REVISION, - OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, - STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, - LocalSystemSid); - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - /* set the DACL in the security descriptor */ - Status = RtlSetDaclSecurityDescriptor(AbsSD, - TRUE, - Dacl, - FALSE); - - /* all done */ - if (NT_SUCCESS(Status)) - { - *SecurityDescriptor = AbsSD; - *SystemSid = LocalSystemSid; - } - else - { -Cleanup: - if (LocalSystemSid != NULL) - { - RtlFreeSid(LocalSystemSid); - } - - if (Dacl != NULL) - { - RtlpFreeMemory(Dacl, - 'cAeS'); - } - - if (AbsSD != NULL) - { - RtlpFreeMemory(AbsSD, - 'dSeS'); - } - } - - return Status; -} - -static NTSTATUS -RtlpSysVolCheckOwnerAndSecurity(IN HANDLE DirectoryHandle, - IN PISECURITY_DESCRIPTOR SecurityDescriptor) +PRTL_BSD_DATA DummyBsd; +RTL_BSD_ITEM_TABLE_ENTRY BsdItemTable[RtlBsdItemMax] = { - PSECURITY_DESCRIPTOR RelSD = NULL; - PSECURITY_DESCRIPTOR NewRelSD = NULL; - PSECURITY_DESCRIPTOR AbsSD = NULL; -#ifdef _WIN64 - BOOLEAN AbsSDAllocated = FALSE; -#endif - PSID AdminSid = NULL; - PSID LocalSystemSid = NULL; - ULONG DescriptorSize; - ULONG AbsSDSize, RelSDSize = 0; - PACL Dacl; - BOOLEAN DaclPresent, DaclDefaulted; - PSID OwnerSid; - BOOLEAN OwnerDefaulted; - ULONG AceIndex; - PACE Ace = NULL; - NTSTATUS Status; - - /* find out how much memory we need to allocate for the self-relative - descriptor we're querying */ - Status = ZwQuerySecurityObject(DirectoryHandle, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - NULL, - 0, - &DescriptorSize); - if (Status != STATUS_BUFFER_TOO_SMALL) - { - /* looks like the FS doesn't support security... return success */ - Status = STATUS_SUCCESS; - goto Cleanup; - } - - /* allocate enough memory for the security descriptor */ - RelSD = RtlpAllocateMemory(DescriptorSize, - 'dSeS'); - if (RelSD == NULL) - { - Status = STATUS_NO_MEMORY; - goto Cleanup; - } - - /* query the self-relative security descriptor */ - Status = ZwQuerySecurityObject(DirectoryHandle, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - RelSD, - DescriptorSize, - &DescriptorSize); - if (!NT_SUCCESS(Status)) - { - /* FIXME - handle the case where someone else modified the owner and/or - DACL while we allocated memory. But that should be *very* - unlikely.... */ - goto Cleanup; - } - - /* query the owner and DACL from the descriptor */ - Status = RtlGetOwnerSecurityDescriptor(RelSD, - &OwnerSid, - &OwnerDefaulted); - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - Status = RtlGetDaclSecurityDescriptor(RelSD, - &DaclPresent, - &Dacl, - &DaclDefaulted); - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - /* create the Administrators SID */ - Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, - 0, - 0, - 0, - 0, - 0, - &AdminSid); - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - /* create the local SYSTEM SID */ - Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, - 1, - SECURITY_LOCAL_SYSTEM_RID, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - &LocalSystemSid); - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - /* check if the Administrators are the owner and at least a not-NULL DACL - is present */ - if (OwnerSid != NULL && - RtlEqualSid(OwnerSid, - AdminSid) && - DaclPresent && Dacl != NULL) - { - /* check the DACL for an Allowed ACE for the SYSTEM account */ - AceIndex = 0; - do - { - Status = RtlGetAce(Dacl, - AceIndex++, - (PVOID*)&Ace); - if (!NT_SUCCESS(Status)) - { - Ace = NULL; - } - else if (Ace != NULL && Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) - { - /* check if the the ACE is a set of allowed permissions for the - local SYSTEM account */ - if (RtlEqualSid((PSID)(Ace + 1), - LocalSystemSid)) - { - /* check if the ACE is inherited by noncontainer and - container objects, if not attempt to change that */ - if (!(Ace->Header.AceFlags & OBJECT_INHERIT_ACE) || - !(Ace->Header.AceFlags & CONTAINER_INHERIT_ACE)) - { - Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; - Status = ZwSetSecurityObject(DirectoryHandle, - DACL_SECURITY_INFORMATION, - RelSD); - } - else - { - /* all done, we have access */ - Status = STATUS_SUCCESS; - } - - goto Cleanup; - } - } - } while (Ace != NULL); - } - - AbsSDSize = DescriptorSize; - - /* because we need to change any existing data we need to convert it to - an absolute security descriptor first */ - Status = RtlSelfRelativeToAbsoluteSD2(RelSD, - &AbsSDSize); -#ifdef _WIN64 - if (Status == STATUS_BUFFER_TOO_SMALL) - { - /* this error code can only be returned on 64 bit builds because - the size of an absolute security descriptor is greater than the - size of a self-relative security descriptor */ - ASSERT(AbsSDSize > DescriptorSize); - - AbsSD = RtlpAllocateMemory(DescriptorSize, - 'dSeS'); - if (AbsSD == NULL) - { - Status = STATUS_NO_MEMORY; - goto Cleanup; - } - - AbsSDAllocated = TRUE; - - /* make a raw copy of the self-relative descriptor */ - RtlCopyMemory(AbsSD, - RelSD, - DescriptorSize); - - /* finally convert it */ - Status = RtlSelfRelativeToAbsoluteSD2(AbsSD, - &AbsSDSize); - } - else -#endif - { - AbsSD = RelSD; - } - - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - /* set the owner SID */ - Status = RtlSetOwnerSecurityDescriptor(AbsSD, - AdminSid, - FALSE); - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - /* set the DACL in the security descriptor */ - Status = RtlSetDaclSecurityDescriptor(AbsSD, - TRUE, - SecurityDescriptor->Dacl, - FALSE); - if (!NT_SUCCESS(Status)) - { - goto Cleanup; - } - - /* convert it back to a self-relative descriptor, find out how much - memory we need */ - Status = RtlAbsoluteToSelfRelativeSD(AbsSD, - NULL, - &RelSDSize); - if (Status != STATUS_BUFFER_TOO_SMALL) - { - goto Cleanup; - } - - /* allocate enough memory for the new self-relative descriptor */ - NewRelSD = RtlpAllocateMemory(RelSDSize, - 'dSeS'); - if (NewRelSD == NULL) - { - Status = STATUS_NO_MEMORY; - goto Cleanup; - } - - /* convert the security descriptor to self-relative format */ - Status = RtlAbsoluteToSelfRelativeSD(AbsSD, - NewRelSD, - &RelSDSize); - if (Status == STATUS_BUFFER_TOO_SMALL) - { - goto Cleanup; - } - - /* finally attempt to change the security information */ - Status = ZwSetSecurityObject(DirectoryHandle, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - NewRelSD); - -Cleanup: - if (AdminSid != NULL) { - RtlFreeSid(AdminSid); - } - - if (LocalSystemSid != NULL) + FIELD_OFFSET(RTL_BSD_DATA, Version), + sizeof(&DummyBsd->Version) + }, // RtlBsdItemVersionNumber { - RtlFreeSid(LocalSystemSid); - } - - if (RelSD != NULL) + FIELD_OFFSET(RTL_BSD_DATA, ProductType), + sizeof(&DummyBsd->ProductType) + }, // RtlBsdItemProductType { - RtlpFreeMemory(RelSD, - 'dSeS'); - } - - if (NewRelSD != NULL) + FIELD_OFFSET(RTL_BSD_DATA, AabEnabled), + sizeof(&DummyBsd->AabEnabled) + }, // RtlBsdItemAabEnabled { - RtlpFreeMemory(NewRelSD, - 'dSeS'); - } - -#ifdef _WIN64 - if (AbsSDAllocated) + FIELD_OFFSET(RTL_BSD_DATA, AabTimeout), + sizeof(&DummyBsd->AabTimeout) + }, // RtlBsdItemAabTimeout { - RtlpFreeMemory(AbsSD, - 'dSeS'); - } -#endif - - return Status; -} - -static NTSTATUS -RtlpSysVolTakeOwnership(IN PUNICODE_STRING DirectoryPath, - IN PSECURITY_DESCRIPTOR SecurityDescriptor) -{ - TOKEN_PRIVILEGES TokenPrivileges; - OBJECT_ATTRIBUTES ObjectAttributes; - SECURITY_DESCRIPTOR AbsSD; - PSID AdminSid = NULL; - IO_STATUS_BLOCK IoStatusBlock; - BOOLEAN TokenEnabled = FALSE; - HANDLE hToken = NULL; - HANDLE hDirectory = NULL; - NTSTATUS Status; - ULONG ReturnLength; - - Status = ZwOpenProcessToken(NtCurrentProcess(), - TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, - &hToken); - if (!NT_SUCCESS(Status)) + FIELD_OFFSET(RTL_BSD_DATA, LastBootSucceeded), + sizeof(&DummyBsd->LastBootSucceeded) + }, // RtlBsdItemBootGood { - goto Cleanup; - } - - /* attempt to enable the SE_TAKE_OWNERSHIP_PRIVILEGE privilege */ - TokenPrivileges.PrivilegeCount = 1; - TokenPrivileges.Privileges[0].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE; - TokenPrivileges.Privileges[0].Luid.HighPart = 0; - TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - Status = ZwAdjustPrivilegesToken(hToken, - FALSE, - &TokenPrivileges, - sizeof(TokenPrivileges), - &TokenPrivileges, - &ReturnLength); - if (!NT_SUCCESS(Status)) + FIELD_OFFSET(RTL_BSD_DATA, LastBootShutdown), + sizeof(&DummyBsd->LastBootShutdown) + }, // RtlBsdItemBootShutdown { - goto Cleanup; - } - TokenEnabled = (TokenPrivileges.PrivilegeCount != 0); - - /* open the directory */ - InitializeObjectAttributes(&ObjectAttributes, - DirectoryPath, - 0, - NULL, - SecurityDescriptor); - - Status = ZwOpenFile(&hDirectory, - SYNCHRONIZE | WRITE_OWNER, - &ObjectAttributes, - &IoStatusBlock, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) + FIELD_OFFSET(RTL_BSD_DATA, SleepInProgress), + sizeof(&DummyBsd->SleepInProgress) + }, // RtlBsdSleepInProgress { - goto Cleanup; - } - - /* create the Administrators SID */ - Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, - 0, - 0, - 0, - 0, - 0, - &AdminSid); - if (!NT_SUCCESS(Status)) + FIELD_OFFSET(RTL_BSD_DATA, PowerTransition), + sizeof(&DummyBsd->PowerTransition) + }, // RtlBsdPowerTransition { - goto Cleanup; - } - - /* create the security descriptor */ - Status = RtlCreateSecurityDescriptor(&AbsSD, - SECURITY_DESCRIPTOR_REVISION); - if (!NT_SUCCESS(Status)) + FIELD_OFFSET(RTL_BSD_DATA, BootAttemptCount), + sizeof(&DummyBsd->BootAttemptCount) + }, // RtlBsdItemBootAttemptCount { - goto Cleanup; - } - - Status = RtlSetOwnerSecurityDescriptor(&AbsSD, - AdminSid, - FALSE); - if (!NT_SUCCESS(Status)) + FIELD_OFFSET(RTL_BSD_DATA, LastBootCheckpoint), + sizeof(&DummyBsd->LastBootCheckpoint) + }, // RtlBsdItemBootCheckpoint { - goto Cleanup; - } - - /* attempt to take ownership */ - Status = ZwSetSecurityObject(hDirectory, - OWNER_SECURITY_INFORMATION, - &AbsSD); - -Cleanup: - if (TokenEnabled) + FIELD_OFFSET(RTL_BSD_DATA, LastBootId), + sizeof(&DummyBsd->LastBootId) + }, // RtlBsdItemBootId { - ZwAdjustPrivilegesToken(hToken, - FALSE, - &TokenPrivileges, - 0, - NULL, - NULL); - } - - if (AdminSid != NULL) + FIELD_OFFSET(RTL_BSD_DATA, LastSuccessfulShutdownBootId), + sizeof(&DummyBsd->LastSuccessfulShutdownBootId) + }, // RtlBsdItemShutdownBootId { - RtlFreeSid(AdminSid); - } - - if (hDirectory != NULL) + FIELD_OFFSET(RTL_BSD_DATA, LastReportedAbnormalShutdownBootId), + sizeof(&DummyBsd->LastReportedAbnormalShutdownBootId) + }, // RtlBsdItemReportedAbnormalShutdownBootId { - ZwClose(hDirectory); - } - - if (hToken != NULL) + FIELD_OFFSET(RTL_BSD_DATA, ErrorInfo), + sizeof(&DummyBsd->ErrorInfo) + }, // RtlBsdItemErrorInfo { - ZwClose(hToken); - } - - return Status; -} - -/* -* @implemented -*/ -NTSTATUS -NTAPI -RtlCreateSystemVolumeInformationFolder(IN PUNICODE_STRING VolumeRootPath) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - HANDLE hDirectory; - UNICODE_STRING DirectoryName, NewPath; - ULONG PathLen; - PISECURITY_DESCRIPTOR SecurityDescriptor = NULL; - PSID SystemSid = NULL; - BOOLEAN AddSep = FALSE; - NTSTATUS Status; - - PAGED_CODE_RTL(); - - RtlInitUnicodeString(&DirectoryName, - L"System Volume Information"); - - PathLen = VolumeRootPath->Length + DirectoryName.Length; - - /* make sure we don't overflow while appending the strings */ - if (PathLen > 0xFFFC) - { - return STATUS_INVALID_PARAMETER; - } - - if (VolumeRootPath->Buffer[(VolumeRootPath->Length / sizeof(WCHAR)) - 1] != L'\\') - { - AddSep = TRUE; - PathLen += sizeof(WCHAR); - } - - /* allocate the new string */ - NewPath.MaximumLength = (USHORT)PathLen + sizeof(WCHAR); - NewPath.Buffer = RtlpAllocateStringMemory(NewPath.MaximumLength, - TAG_USTR); - if (NewPath.Buffer == NULL) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* create the new path string */ - NewPath.Length = VolumeRootPath->Length; - RtlCopyMemory(NewPath.Buffer, - VolumeRootPath->Buffer, - NewPath.Length); - if (AddSep) - { - NewPath.Buffer[NewPath.Length / sizeof(WCHAR)] = L'\\'; - NewPath.Length += sizeof(WCHAR); - } - RtlCopyMemory(NewPath.Buffer + (NewPath.Length / sizeof(WCHAR)), - DirectoryName.Buffer, - DirectoryName.Length); - NewPath.Length += DirectoryName.Length; - NewPath.Buffer[NewPath.Length / sizeof(WCHAR)] = L'\0'; - - ASSERT(NewPath.Length == PathLen); - ASSERT(NewPath.Length == NewPath.MaximumLength - sizeof(WCHAR)); - - /* create the security descriptor for the new directory */ - Status = RtlpSysVolCreateSecurityDescriptor(&SecurityDescriptor, - &SystemSid); - if (NT_SUCCESS(Status)) + FIELD_OFFSET(RTL_BSD_DATA, PowerButtonPressInfo), + sizeof(&DummyBsd->PowerButtonPressInfo) + }, // RtlBsdItemPowerButtonPressInfo { - /* create or open the directory */ - InitializeObjectAttributes(&ObjectAttributes, - &NewPath, - 0, - NULL, - SecurityDescriptor); - - Status = ZwCreateFile(&hDirectory, - SYNCHRONIZE | WRITE_OWNER | WRITE_DAC | READ_CONTROL, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - FILE_OPEN_IF, - FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - Status = RtlpSysVolTakeOwnership(&NewPath, - SecurityDescriptor); - - if (NT_SUCCESS(Status)) - { - /* successfully took ownership, attempt to open it */ - Status = ZwCreateFile(&hDirectory, - SYNCHRONIZE | WRITE_OWNER | WRITE_DAC | READ_CONTROL, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - FILE_OPEN_IF, - FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - } - } - - if (NT_SUCCESS(Status)) - { - /* check security now and adjust it if neccessary */ - Status = RtlpSysVolCheckOwnerAndSecurity(hDirectory, - SecurityDescriptor); - ZwClose(hDirectory); - } - - /* free allocated memory */ - ASSERT(SecurityDescriptor != NULL); - ASSERT(SecurityDescriptor->Dacl != NULL); - - RtlpFreeMemory(SecurityDescriptor->Dacl, - 'cAeS'); - RtlpFreeMemory(SecurityDescriptor, - 'dSeS'); - - RtlFreeSid(SystemSid); - } - - RtlpFreeStringMemory(NewPath.Buffer, - TAG_USTR); - return Status; -} + FIELD_OFFSET(RTL_BSD_DATA, Checksum), + sizeof(&DummyBsd->Checksum) + }, // RtlBsdItemChecksum +}; /* -* @implemented -*/ + * @implemented + */ NTSTATUS NTAPI -RtlCreateBootStatusDataFile(VOID) +RtlCreateBootStatusDataFile ( + VOID + ) { - OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER AllocationSize; LARGE_INTEGER ByteOffset; - UNICODE_STRING FileName; + UNICODE_STRING FileName = + RTL_CONSTANT_STRING(L"\\SystemRoot\\bootstat.dat"); + OBJECT_ATTRIBUTES ObjectAttributes = + RTL_CONSTANT_OBJECT_ATTRIBUTES(&FileName, OBJ_CASE_INSENSITIVE); HANDLE FileHandle; NTSTATUS Status; + RTL_BSD_DATA InitialBsd; - /* Initialize the file name */ - RtlInitUnicodeString(&FileName, - L"\\SystemRoot\\bootstat.dat"); - - /* Initialize the object attributes */ - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - + /* Create the boot status data file */ AllocationSize.QuadPart = 0x800; DBG_UNREFERENCED_LOCAL_VARIABLE(AllocationSize); - - /* Create the boot status data file */ Status = ZwCreateFile(&FileHandle, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &ObjectAttributes, @@ -723,17 +126,23 @@ RtlCreateBootStatusDataFile(VOID) 0); if (NT_SUCCESS(Status)) { - // FIXME: Initialize the buffer in a better way. - UCHAR Buffer[12] = {0xC,0,0,0, 1,0,0,0, 1, 0x1e, 1, 0}; + /* Setup a sane looking initial BSD */ + RtlZeroMemory(&InitialBsd, sizeof(InitialBsd)); + InitialBsd.Version = sizeof(InitialBsd); + InitialBsd.ProductType = NtProductWinNt; + InitialBsd.AabEnabled = 1; + InitialBsd.AabTimeout = 30; + InitialBsd.LastBootSucceeded = TRUE; + /* Write it to disk */ ByteOffset.QuadPart = 0; Status = ZwWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, - &Buffer, - 12, //BufferSize, + &InitialBsd, + sizeof(InitialBsd), &ByteOffset, NULL); } @@ -745,34 +154,40 @@ RtlCreateBootStatusDataFile(VOID) } /* -* @implemented -*/ + * @implemented + */ NTSTATUS NTAPI -RtlGetSetBootStatusData(IN HANDLE FileHandle, - IN BOOLEAN WriteMode, - IN RTL_BSD_ITEM_TYPE DataClass, - IN PVOID Buffer, - IN ULONG BufferSize, - OUT PULONG ReturnLength) +RtlGetSetBootStatusData ( + _In_ HANDLE FileHandle, + _In_ BOOLEAN Read, + _In_ RTL_BSD_ITEM_TYPE DataClass, + _In_ PVOID Buffer, + _In_ ULONG BufferSize, + _Out_opt_ PULONG ReturnLength + ) { IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER ByteOffset; NTSTATUS Status; DPRINT("RtlGetSetBootStatusData (%p %u %d %p %lu %p)\n", - FileHandle, WriteMode, DataClass, Buffer, BufferSize, ReturnLength); + FileHandle, Read, DataClass, Buffer, BufferSize, ReturnLength); if (DataClass >= RtlBsdItemMax) + { return STATUS_INVALID_PARAMETER; + } if (BufferSize > BsdItemTable[DataClass].Size) + { return STATUS_BUFFER_TOO_SMALL; + } ByteOffset.HighPart = 0; ByteOffset.LowPart = BsdItemTable[DataClass].Offset; - if (WriteMode) + if (Read) { Status = ZwReadFile(FileHandle, NULL, @@ -800,39 +215,34 @@ RtlGetSetBootStatusData(IN HANDLE FileHandle, if (NT_SUCCESS(Status)) { if (ReturnLength) + { *ReturnLength = BsdItemTable[DataClass].Size; + } } return Status; } /* -* @implemented -*/ + * @implemented + */ NTSTATUS NTAPI -RtlLockBootStatusData(OUT PHANDLE FileHandle) +RtlLockBootStatusData ( + _Out_ PHANDLE FileHandle + ) { - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING FileName; + UNICODE_STRING FileName = + RTL_CONSTANT_STRING(L"\\SystemRoot\\bootstat.dat"); + OBJECT_ATTRIBUTES ObjectAttributes = + RTL_CONSTANT_OBJECT_ATTRIBUTES(&FileName, OBJ_CASE_INSENSITIVE); HANDLE LocalFileHandle; NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; /* Intialize the file handle */ *FileHandle = NULL; - /* Initialize the file name */ - RtlInitUnicodeString(&FileName, - L"\\SystemRoot\\bootstat.dat"); - - /* Initialize the object attributes */ - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - 0, - NULL, - NULL); - /* Open the boot status data file */ Status = ZwOpenFile(&LocalFileHandle, FILE_ALL_ACCESS, @@ -850,18 +260,18 @@ RtlLockBootStatusData(OUT PHANDLE FileHandle) } /* -* @implemented -*/ + * @implemented + */ NTSTATUS NTAPI -RtlUnlockBootStatusData(IN HANDLE FileHandle) +RtlUnlockBootStatusData ( + _In_ HANDLE FileHandle + ) { IO_STATUS_BLOCK IoStatusBlock; /* Flush the file and close it */ - ZwFlushBuffersFile(FileHandle, - &IoStatusBlock); - + ZwFlushBuffersFile(FileHandle, &IoStatusBlock); return ZwClose(FileHandle); } diff --git a/sdk/lib/rtl/bootdata.c b/sdk/lib/rtl/sysvol.c similarity index 80% copy from sdk/lib/rtl/bootdata.c copy to sdk/lib/rtl/sysvol.c index 77d367426d..67c79df065 100644 --- a/sdk/lib/rtl/bootdata.c +++ b/sdk/lib/rtl/sysvol.c @@ -9,22 +9,13 @@ /* INCLUDES *****************************************************************/ #include <rtl.h> - #define NDEBUG #include <debug.h> -typedef struct _RTL_BSD_ITEM -{ - ULONG Offset; - ULONG Size; -} RTL_BSD_ITEM, *PRTL_BSD_ITEM; - /* FUNCTIONS *****************************************************************/ static SID_IDENTIFIER_AUTHORITY LocalSystemAuthority = {SECURITY_NT_AUTHORITY}; -static RTL_BSD_ITEM BsdItemTable[6] = {{0, 4}, {4, 4,}, {8, 1}, {9, 1}, {10, 1}, {11, 1}}; - static NTSTATUS RtlpSysVolCreateSecurityDescriptor(OUT PISECURITY_DESCRIPTOR *SecurityDescriptor, OUT PSID *SystemSid) @@ -680,189 +671,4 @@ RtlCreateSystemVolumeInformationFolder(IN PUNICODE_STRING VolumeRootPath) return Status; } -/* -* @implemented -*/ -NTSTATUS -NTAPI -RtlCreateBootStatusDataFile(VOID) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - LARGE_INTEGER AllocationSize; - LARGE_INTEGER ByteOffset; - UNICODE_STRING FileName; - HANDLE FileHandle; - NTSTATUS Status; - - /* Initialize the file name */ - RtlInitUnicodeString(&FileName, - L"\\SystemRoot\\bootstat.dat"); - - /* Initialize the object attributes */ - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - AllocationSize.QuadPart = 0x800; - DBG_UNREFERENCED_LOCAL_VARIABLE(AllocationSize); - - /* Create the boot status data file */ - Status = ZwCreateFile(&FileHandle, - FILE_GENERIC_READ | FILE_GENERIC_WRITE, - &ObjectAttributes, - &IoStatusBlock, - NULL, //&AllocationSize, - FILE_ATTRIBUTE_SYSTEM, - 0, - FILE_CREATE, - FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - if (NT_SUCCESS(Status)) - { - // FIXME: Initialize the buffer in a better way. - UCHAR Buffer[12] = {0xC,0,0,0, 1,0,0,0, 1, 0x1e, 1, 0}; - - ByteOffset.QuadPart = 0; - Status = ZwWriteFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - &Buffer, - 12, //BufferSize, - &ByteOffset, - NULL); - } - - /* Close the file */ - ZwClose(FileHandle); - - return Status; -} - -/* -* @implemented -*/ -NTSTATUS -NTAPI -RtlGetSetBootStatusData(IN HANDLE FileHandle, - IN BOOLEAN WriteMode, - IN RTL_BSD_ITEM_TYPE DataClass, - IN PVOID Buffer, - IN ULONG BufferSize, - OUT PULONG ReturnLength) -{ - IO_STATUS_BLOCK IoStatusBlock; - LARGE_INTEGER ByteOffset; - NTSTATUS Status; - - DPRINT("RtlGetSetBootStatusData (%p %u %d %p %lu %p)\n", - FileHandle, WriteMode, DataClass, Buffer, BufferSize, ReturnLength); - - if (DataClass >= RtlBsdItemMax) - return STATUS_INVALID_PARAMETER; - - if (BufferSize > BsdItemTable[DataClass].Size) - return STATUS_BUFFER_TOO_SMALL; - - ByteOffset.HighPart = 0; - ByteOffset.LowPart = BsdItemTable[DataClass].Offset; - - if (WriteMode) - { - Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - Buffer, - BufferSize, - &ByteOffset, - NULL); - } - else - { - Status = ZwWriteFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - Buffer, - BufferSize, - &ByteOffset, - NULL); - } - - if (NT_SUCCESS(Status)) - { - if (ReturnLength) - *ReturnLength = BsdItemTable[DataClass].Size; - } - - return Status; -} - -/* -* @implemented -*/ -NTSTATUS -NTAPI -RtlLockBootStatusData(OUT PHANDLE FileHandle) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING FileName; - HANDLE LocalFileHandle; - NTSTATUS Status; - - /* Intialize the file handle */ - *FileHandle = NULL; - - /* Initialize the file name */ - RtlInitUnicodeString(&FileName, - L"\\SystemRoot\\bootstat.dat"); - - /* Initialize the object attributes */ - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - 0, - NULL, - NULL); - - /* Open the boot status data file */ - Status = ZwOpenFile(&LocalFileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (NT_SUCCESS(Status)) - { - /* Return the file handle */ - *FileHandle = LocalFileHandle; - } - - return Status; -} - -/* -* @implemented -*/ -NTSTATUS -NTAPI -RtlUnlockBootStatusData(IN HANDLE FileHandle) -{ - IO_STATUS_BLOCK IoStatusBlock; - - /* Flush the file and close it */ - ZwFlushBuffersFile(FileHandle, - &IoStatusBlock); - - return ZwClose(FileHandle); -} - /* EOF */