xref: /reactos/sdk/lib/rtl/bootdata.c (revision 595b846d)
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