1 /* 2 * PROJECT: ReactOS Runtime Library 3 * LICENSE: See COPYING in the top level directory 4 * FILE: lib/rtl/bootdata.c 5 * PURPOSE: Boot Status Data Implementation 6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 7 * Eric Kohl 8 */ 9 10 /* INCLUDES *****************************************************************/ 11 12 #include <rtl.h> 13 #define NDEBUG 14 #include <debug.h> 15 16 typedef struct _RTL_BSD_ITEM_TABLE_ENTRY 17 { 18 UCHAR Offset; 19 UCHAR Size; 20 } RTL_BSD_ITEM_TABLE_ENTRY; 21 22 /* FUNCTIONS *****************************************************************/ 23 24 PRTL_BSD_DATA DummyBsd; 25 RTL_BSD_ITEM_TABLE_ENTRY BsdItemTable[RtlBsdItemMax] = 26 { 27 { 28 FIELD_OFFSET(RTL_BSD_DATA, Version), 29 sizeof(&DummyBsd->Version) 30 }, // RtlBsdItemVersionNumber 31 { 32 FIELD_OFFSET(RTL_BSD_DATA, ProductType), 33 sizeof(&DummyBsd->ProductType) 34 }, // RtlBsdItemProductType 35 { 36 FIELD_OFFSET(RTL_BSD_DATA, AabEnabled), 37 sizeof(&DummyBsd->AabEnabled) 38 }, // RtlBsdItemAabEnabled 39 { 40 FIELD_OFFSET(RTL_BSD_DATA, AabTimeout), 41 sizeof(&DummyBsd->AabTimeout) 42 }, // RtlBsdItemAabTimeout 43 { 44 FIELD_OFFSET(RTL_BSD_DATA, LastBootSucceeded), 45 sizeof(&DummyBsd->LastBootSucceeded) 46 }, // RtlBsdItemBootGood 47 { 48 FIELD_OFFSET(RTL_BSD_DATA, LastBootShutdown), 49 sizeof(&DummyBsd->LastBootShutdown) 50 }, // RtlBsdItemBootShutdown 51 { 52 FIELD_OFFSET(RTL_BSD_DATA, SleepInProgress), 53 sizeof(&DummyBsd->SleepInProgress) 54 }, // RtlBsdSleepInProgress 55 { 56 FIELD_OFFSET(RTL_BSD_DATA, PowerTransition), 57 sizeof(&DummyBsd->PowerTransition) 58 }, // RtlBsdPowerTransition 59 { 60 FIELD_OFFSET(RTL_BSD_DATA, BootAttemptCount), 61 sizeof(&DummyBsd->BootAttemptCount) 62 }, // RtlBsdItemBootAttemptCount 63 { 64 FIELD_OFFSET(RTL_BSD_DATA, LastBootCheckpoint), 65 sizeof(&DummyBsd->LastBootCheckpoint) 66 }, // RtlBsdItemBootCheckpoint 67 { 68 FIELD_OFFSET(RTL_BSD_DATA, LastBootId), 69 sizeof(&DummyBsd->LastBootId) 70 }, // RtlBsdItemBootId 71 { 72 FIELD_OFFSET(RTL_BSD_DATA, LastSuccessfulShutdownBootId), 73 sizeof(&DummyBsd->LastSuccessfulShutdownBootId) 74 }, // RtlBsdItemShutdownBootId 75 { 76 FIELD_OFFSET(RTL_BSD_DATA, LastReportedAbnormalShutdownBootId), 77 sizeof(&DummyBsd->LastReportedAbnormalShutdownBootId) 78 }, // RtlBsdItemReportedAbnormalShutdownBootId 79 { 80 FIELD_OFFSET(RTL_BSD_DATA, ErrorInfo), 81 sizeof(&DummyBsd->ErrorInfo) 82 }, // RtlBsdItemErrorInfo 83 { 84 FIELD_OFFSET(RTL_BSD_DATA, PowerButtonPressInfo), 85 sizeof(&DummyBsd->PowerButtonPressInfo) 86 }, // RtlBsdItemPowerButtonPressInfo 87 { 88 FIELD_OFFSET(RTL_BSD_DATA, Checksum), 89 sizeof(&DummyBsd->Checksum) 90 }, // RtlBsdItemChecksum 91 }; 92 93 /* 94 * @implemented 95 */ 96 NTSTATUS 97 NTAPI 98 RtlCreateBootStatusDataFile ( 99 VOID 100 ) 101 { 102 IO_STATUS_BLOCK IoStatusBlock; 103 LARGE_INTEGER AllocationSize; 104 LARGE_INTEGER ByteOffset; 105 UNICODE_STRING FileName = 106 RTL_CONSTANT_STRING(L"\\SystemRoot\\bootstat.dat"); 107 OBJECT_ATTRIBUTES ObjectAttributes = 108 RTL_CONSTANT_OBJECT_ATTRIBUTES(&FileName, OBJ_CASE_INSENSITIVE); 109 HANDLE FileHandle; 110 NTSTATUS Status; 111 RTL_BSD_DATA InitialBsd; 112 113 /* Create the boot status data file */ 114 AllocationSize.QuadPart = 0x800; 115 DBG_UNREFERENCED_LOCAL_VARIABLE(AllocationSize); 116 Status = ZwCreateFile(&FileHandle, 117 FILE_GENERIC_READ | FILE_GENERIC_WRITE, 118 &ObjectAttributes, 119 &IoStatusBlock, 120 NULL, //&AllocationSize, 121 FILE_ATTRIBUTE_SYSTEM, 122 0, 123 FILE_CREATE, 124 FILE_SYNCHRONOUS_IO_NONALERT, 125 NULL, 126 0); 127 if (NT_SUCCESS(Status)) 128 { 129 /* Setup a sane looking initial BSD */ 130 RtlZeroMemory(&InitialBsd, sizeof(InitialBsd)); 131 InitialBsd.Version = sizeof(InitialBsd); 132 InitialBsd.ProductType = NtProductWinNt; 133 InitialBsd.AabEnabled = 1; 134 InitialBsd.AabTimeout = 30; 135 InitialBsd.LastBootSucceeded = TRUE; 136 137 /* Write it to disk */ 138 ByteOffset.QuadPart = 0; 139 Status = ZwWriteFile(FileHandle, 140 NULL, 141 NULL, 142 NULL, 143 &IoStatusBlock, 144 &InitialBsd, 145 sizeof(InitialBsd), 146 &ByteOffset, 147 NULL); 148 } 149 150 /* Close the file */ 151 ZwClose(FileHandle); 152 153 return Status; 154 } 155 156 /* 157 * @implemented 158 */ 159 NTSTATUS 160 NTAPI 161 RtlGetSetBootStatusData ( 162 _In_ HANDLE FileHandle, 163 _In_ BOOLEAN Read, 164 _In_ RTL_BSD_ITEM_TYPE DataClass, 165 _In_ PVOID Buffer, 166 _In_ ULONG BufferSize, 167 _Out_opt_ PULONG ReturnLength 168 ) 169 { 170 IO_STATUS_BLOCK IoStatusBlock; 171 LARGE_INTEGER ByteOffset; 172 NTSTATUS Status; 173 174 DPRINT("RtlGetSetBootStatusData (%p %u %d %p %lu %p)\n", 175 FileHandle, Read, DataClass, Buffer, BufferSize, ReturnLength); 176 177 if (DataClass >= RtlBsdItemMax) 178 { 179 return STATUS_INVALID_PARAMETER; 180 } 181 182 if (BufferSize > BsdItemTable[DataClass].Size) 183 { 184 return STATUS_BUFFER_TOO_SMALL; 185 } 186 187 ByteOffset.HighPart = 0; 188 ByteOffset.LowPart = BsdItemTable[DataClass].Offset; 189 190 if (Read) 191 { 192 Status = ZwReadFile(FileHandle, 193 NULL, 194 NULL, 195 NULL, 196 &IoStatusBlock, 197 Buffer, 198 BufferSize, 199 &ByteOffset, 200 NULL); 201 } 202 else 203 { 204 Status = ZwWriteFile(FileHandle, 205 NULL, 206 NULL, 207 NULL, 208 &IoStatusBlock, 209 Buffer, 210 BufferSize, 211 &ByteOffset, 212 NULL); 213 } 214 215 if (NT_SUCCESS(Status)) 216 { 217 if (ReturnLength) 218 { 219 *ReturnLength = BsdItemTable[DataClass].Size; 220 } 221 } 222 223 return Status; 224 } 225 226 /* 227 * @implemented 228 */ 229 NTSTATUS 230 NTAPI 231 RtlLockBootStatusData ( 232 _Out_ PHANDLE FileHandle 233 ) 234 { 235 UNICODE_STRING FileName = 236 RTL_CONSTANT_STRING(L"\\SystemRoot\\bootstat.dat"); 237 OBJECT_ATTRIBUTES ObjectAttributes = 238 RTL_CONSTANT_OBJECT_ATTRIBUTES(&FileName, OBJ_CASE_INSENSITIVE); 239 HANDLE LocalFileHandle; 240 NTSTATUS Status; 241 IO_STATUS_BLOCK IoStatusBlock; 242 243 /* Intialize the file handle */ 244 *FileHandle = NULL; 245 246 /* Open the boot status data file */ 247 Status = ZwOpenFile(&LocalFileHandle, 248 FILE_ALL_ACCESS, 249 &ObjectAttributes, 250 &IoStatusBlock, 251 0, 252 FILE_SYNCHRONOUS_IO_NONALERT); 253 if (NT_SUCCESS(Status)) 254 { 255 /* Return the file handle */ 256 *FileHandle = LocalFileHandle; 257 } 258 259 return Status; 260 } 261 262 /* 263 * @implemented 264 */ 265 NTSTATUS 266 NTAPI 267 RtlUnlockBootStatusData ( 268 _In_ HANDLE FileHandle 269 ) 270 { 271 IO_STATUS_BLOCK IoStatusBlock; 272 273 /* Flush the file and close it */ 274 ZwFlushBuffersFile(FileHandle, &IoStatusBlock); 275 return ZwClose(FileHandle); 276 } 277 278 /* EOF */ 279