]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
ArmPlatformPkg/BootMonFs: Fix permission check in SetFileInfo
[mirror_edk2.git] / ArmPlatformPkg / FileSystem / BootMonFs / BootMonFsReadWrite.c
1 /** @file
2 *
3 * Copyright (c) 2012-2014, ARM Limited. All rights reserved.
4 *
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
9 *
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14
15 #include <Protocol/SimpleFileSystem.h>
16 #include <Library/UefiLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/DebugLib.h>
20
21 #include "BootMonFsInternal.h"
22
23 EFIAPI
24 EFI_STATUS
25 BootMonFsReadFile (
26 IN EFI_FILE_PROTOCOL *This,
27 IN OUT UINTN *BufferSize,
28 OUT VOID *Buffer
29 )
30 {
31 BOOTMON_FS_INSTANCE *Instance;
32 BOOTMON_FS_FILE *File;
33 EFI_DISK_IO_PROTOCOL *DiskIo;
34 EFI_BLOCK_IO_MEDIA *Media;
35 UINT64 FileStart;
36 EFI_STATUS Status;
37 UINTN RemainingFileSize;
38
39 // Ensure the file has been written in Flash before reading it.
40 // This keeps the code simple and avoids having to manage a non-flushed file.
41 BootMonFsFlushFile (This);
42
43 File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
44 if (File == NULL) {
45 return EFI_INVALID_PARAMETER;
46 }
47
48 Instance = File->Instance;
49 DiskIo = Instance->DiskIo;
50 Media = Instance->Media;
51 FileStart = (Media->LowestAlignedLba + File->HwDescription.BlockStart) * Media->BlockSize;
52
53 if (File->Position >= File->HwDescription.Region[0].Size) {
54 // The entire file has been read
55 *BufferSize = 0;
56 return EFI_DEVICE_ERROR;
57 }
58
59 // This driver assumes that the entire file is in region 0.
60 RemainingFileSize = File->HwDescription.Region[0].Size - File->Position;
61
62 // If read would go past end of file, truncate the read
63 if (*BufferSize > RemainingFileSize) {
64 *BufferSize = RemainingFileSize;
65 }
66
67 Status = DiskIo->ReadDisk (
68 DiskIo,
69 Media->MediaId,
70 FileStart + File->Position,
71 *BufferSize,
72 Buffer
73 );
74 if (EFI_ERROR (Status)) {
75 *BufferSize = 0;
76 }
77
78 File->Position += *BufferSize;
79
80 return Status;
81 }
82
83 // Inserts an entry into the write chain
84 EFIAPI
85 EFI_STATUS
86 BootMonFsWriteFile (
87 IN EFI_FILE_PROTOCOL *This,
88 IN OUT UINTN *BufferSize,
89 IN VOID *Buffer
90 )
91 {
92 BOOTMON_FS_FILE *File;
93 BOOTMON_FS_FILE_REGION *Region;
94
95 File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
96 if (File == NULL) {
97 return EFI_INVALID_PARAMETER;
98 }
99
100 if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {
101 return EFI_ACCESS_DENIED;
102 }
103
104 // Allocate and initialize the memory region
105 Region = (BOOTMON_FS_FILE_REGION*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE_REGION));
106 if (Region == NULL) {
107 return EFI_OUT_OF_RESOURCES;
108 }
109
110 Region->Buffer = AllocateCopyPool (*BufferSize, Buffer);
111 if (Region->Buffer == NULL) {
112 FreePool (Region);
113 return EFI_OUT_OF_RESOURCES;
114 }
115
116 Region->Size = *BufferSize;
117
118 Region->Offset = File->Position;
119
120 InsertTailList (&File->RegionToFlushLink, &Region->Link);
121
122 File->Position += *BufferSize;
123
124 return EFI_SUCCESS;
125 }
126
127 EFIAPI
128 EFI_STATUS
129 BootMonFsSetPosition (
130 IN EFI_FILE_PROTOCOL *This,
131 IN UINT64 Position
132 )
133 {
134 BOOTMON_FS_FILE *File;
135
136 File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
137
138 // UEFI Spec section 12.5:
139 // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to
140 // be set to the end of the file."
141 if (Position == 0xFFFFFFFFFFFFFFFF) {
142 File->Position = BootMonFsGetImageLength (File);
143 } else {
144 // NB: Seeking past the end of the file is valid.
145 File->Position = Position;
146 }
147
148 return EFI_SUCCESS;
149 }
150
151 EFIAPI
152 EFI_STATUS
153 BootMonFsGetPosition (
154 IN EFI_FILE_PROTOCOL *This,
155 OUT UINT64 *Position
156 ) {
157 BOOTMON_FS_FILE *File;
158
159 File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
160
161 *Position = File->Position;
162 return EFI_SUCCESS;
163 }