reactos/sdk/lib/rtl/bootdata.c

279 lines
7.4 KiB
C
Raw Normal View History

/*
* 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 */