xref: /reactos/base/setup/lib/bootcode.c (revision 53221834)
1 /*
2  * PROJECT:     ReactOS Setup Library
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     BootCode support functions.
5  * COPYRIGHT:   Copyright 2020 Hermes Belusca-Maito
6  */
7 
8 /* INCLUDES *****************************************************************/
9 
10 #include "precomp.h"
11 
12 #include "bootcode.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 
18 /* FUNCTIONS ****************************************************************/
19 
20 NTSTATUS
21 ReadBootCodeByHandle(
22     IN OUT PBOOTCODE BootCodeInfo,
23     IN HANDLE FileHandle,
24     IN ULONG Length OPTIONAL)
25 {
26     NTSTATUS Status;
27     PVOID BootCode;
28     IO_STATUS_BLOCK IoStatusBlock;
29     LARGE_INTEGER FileOffset;
30 
31     ASSERT(BootCodeInfo);
32 
33     /* Normalize the bootcode length */
34     if (Length == 0 || Length == (ULONG)-1)
35         Length = SECTORSIZE;
36 
37     /* Allocate a buffer for the bootcode */
38     BootCode = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, Length);
39     if (BootCode == NULL)
40         return STATUS_INSUFFICIENT_RESOURCES;
41 
42     /* Read the bootcode from the file into the buffer */
43     FileOffset.QuadPart = 0ULL;
44     Status = NtReadFile(FileHandle,
45                         NULL,
46                         NULL,
47                         NULL,
48                         &IoStatusBlock,
49                         BootCode,
50                         Length,
51                         &FileOffset,
52                         NULL);
53     if (!NT_SUCCESS(Status))
54     {
55         RtlFreeHeap(ProcessHeap, 0, BootCode);
56         return Status;
57     }
58 
59     /* Update the bootcode information */
60     if (BootCodeInfo->BootCode)
61         RtlFreeHeap(ProcessHeap, 0, BootCodeInfo->BootCode);
62     BootCodeInfo->BootCode = BootCode;
63     /**/ BootCodeInfo->Length = Length; /**/
64 
65     return STATUS_SUCCESS;
66 }
67 
68 NTSTATUS
69 ReadBootCodeFromFile(
70     IN OUT PBOOTCODE BootCodeInfo,
71     IN PUNICODE_STRING FilePath,
72     IN ULONG Length OPTIONAL)
73 {
74     NTSTATUS Status;
75     OBJECT_ATTRIBUTES ObjectAttributes;
76     IO_STATUS_BLOCK IoStatusBlock;
77     HANDLE FileHandle;
78 
79     ASSERT(BootCodeInfo);
80 
81     /* Open the file */
82     InitializeObjectAttributes(&ObjectAttributes,
83                                FilePath,
84                                OBJ_CASE_INSENSITIVE,
85                                NULL,
86                                NULL);
87     Status = NtOpenFile(&FileHandle,
88                         GENERIC_READ | SYNCHRONIZE,
89                         &ObjectAttributes,
90                         &IoStatusBlock,
91                         FILE_SHARE_READ | FILE_SHARE_WRITE, // Is FILE_SHARE_WRITE necessary?
92                         FILE_SYNCHRONOUS_IO_NONALERT);
93     if (!NT_SUCCESS(Status))
94         return Status;
95 
96     Status = ReadBootCodeByHandle(BootCodeInfo, FileHandle, Length);
97 
98     /* Close the file and return */
99     NtClose(FileHandle);
100     return Status;
101 }
102 
103 VOID
104 FreeBootCode(
105     IN OUT PBOOTCODE BootCodeInfo)
106 {
107     ASSERT(BootCodeInfo);
108 
109     /* Update the bootcode information */
110     if (BootCodeInfo->BootCode)
111         RtlFreeHeap(ProcessHeap, 0, BootCodeInfo->BootCode);
112     BootCodeInfo->BootCode = NULL;
113     /**/ BootCodeInfo->Length = 0; /**/
114 }
115 
116 /* EOF */
117