reactos/sdk/lib/rtl/bootdata.c
Alex Ionescu 16e0cca7e1 [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.
2018-02-04 09:33:32 -08:00

279 lines
7.4 KiB
C

/*
* PROJECT: ReactOS Runtime Library
* LICENSE: See COPYING in the top level directory
* FILE: lib/rtl/bootdata.c
* PURPOSE: Boot Status Data Implementation
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
*/
/* INCLUDES *****************************************************************/
#include <rtl.h>
#define NDEBUG
#include <debug.h>
typedef struct _RTL_BSD_ITEM_TABLE_ENTRY
{
UCHAR Offset;
UCHAR Size;
} RTL_BSD_ITEM_TABLE_ENTRY;
/* FUNCTIONS *****************************************************************/
PRTL_BSD_DATA DummyBsd;
RTL_BSD_ITEM_TABLE_ENTRY BsdItemTable[RtlBsdItemMax] =
{
{
FIELD_OFFSET(RTL_BSD_DATA, Version),
sizeof(&DummyBsd->Version)
}, // RtlBsdItemVersionNumber
{
FIELD_OFFSET(RTL_BSD_DATA, ProductType),
sizeof(&DummyBsd->ProductType)
}, // RtlBsdItemProductType
{
FIELD_OFFSET(RTL_BSD_DATA, AabEnabled),
sizeof(&DummyBsd->AabEnabled)
}, // RtlBsdItemAabEnabled
{
FIELD_OFFSET(RTL_BSD_DATA, AabTimeout),
sizeof(&DummyBsd->AabTimeout)
}, // RtlBsdItemAabTimeout
{
FIELD_OFFSET(RTL_BSD_DATA, LastBootSucceeded),
sizeof(&DummyBsd->LastBootSucceeded)
}, // RtlBsdItemBootGood
{
FIELD_OFFSET(RTL_BSD_DATA, LastBootShutdown),
sizeof(&DummyBsd->LastBootShutdown)
}, // RtlBsdItemBootShutdown
{
FIELD_OFFSET(RTL_BSD_DATA, SleepInProgress),
sizeof(&DummyBsd->SleepInProgress)
}, // RtlBsdSleepInProgress
{
FIELD_OFFSET(RTL_BSD_DATA, PowerTransition),
sizeof(&DummyBsd->PowerTransition)
}, // RtlBsdPowerTransition
{
FIELD_OFFSET(RTL_BSD_DATA, BootAttemptCount),
sizeof(&DummyBsd->BootAttemptCount)
}, // RtlBsdItemBootAttemptCount
{
FIELD_OFFSET(RTL_BSD_DATA, LastBootCheckpoint),
sizeof(&DummyBsd->LastBootCheckpoint)
}, // RtlBsdItemBootCheckpoint
{
FIELD_OFFSET(RTL_BSD_DATA, LastBootId),
sizeof(&DummyBsd->LastBootId)
}, // RtlBsdItemBootId
{
FIELD_OFFSET(RTL_BSD_DATA, LastSuccessfulShutdownBootId),
sizeof(&DummyBsd->LastSuccessfulShutdownBootId)
}, // RtlBsdItemShutdownBootId
{
FIELD_OFFSET(RTL_BSD_DATA, LastReportedAbnormalShutdownBootId),
sizeof(&DummyBsd->LastReportedAbnormalShutdownBootId)
}, // RtlBsdItemReportedAbnormalShutdownBootId
{
FIELD_OFFSET(RTL_BSD_DATA, ErrorInfo),
sizeof(&DummyBsd->ErrorInfo)
}, // RtlBsdItemErrorInfo
{
FIELD_OFFSET(RTL_BSD_DATA, PowerButtonPressInfo),
sizeof(&DummyBsd->PowerButtonPressInfo)
}, // RtlBsdItemPowerButtonPressInfo
{
FIELD_OFFSET(RTL_BSD_DATA, Checksum),
sizeof(&DummyBsd->Checksum)
}, // RtlBsdItemChecksum
};
/*
* @implemented
*/
NTSTATUS
NTAPI
RtlCreateBootStatusDataFile (
VOID
)
{
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER ByteOffset;
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;
/* Create the boot status data file */
AllocationSize.QuadPart = 0x800;
DBG_UNREFERENCED_LOCAL_VARIABLE(AllocationSize);
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))
{
/* 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,
&InitialBsd,
sizeof(InitialBsd),
&ByteOffset,
NULL);
}
/* Close the file */
ZwClose(FileHandle);
return Status;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
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, 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 (Read)
{
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
)
{
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;
/* 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 */