Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279/* * 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 */NTSTATUSNTAPIRtlCreateBootStatusDataFile ( 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 */NTSTATUSNTAPIRtlGetSetBootStatusData ( _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 */NTSTATUSNTAPIRtlLockBootStatusData ( _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 */NTSTATUSNTAPIRtlUnlockBootStatusData ( _In_ HANDLE FileHandle ){ IO_STATUS_BLOCK IoStatusBlock;
/* Flush the file and close it */ ZwFlushBuffersFile(FileHandle, &IoStatusBlock); return ZwClose(FileHandle);}
/* EOF */