1 use crate::time::Time;
2 use crate::{guid, Char16, Event, Guid, Status};
3 use bitflags::bitflags;
4 use core::ffi::c_void;
5 
6 #[derive(Debug)]
7 #[repr(C)]
8 pub struct SimpleFileSystemProtocol {
9     pub revision: u64,
10     pub open_volume:
11         unsafe extern "efiapi" fn(this: *mut Self, root: *mut *mut FileProtocolV1) -> Status,
12 }
13 
14 impl SimpleFileSystemProtocol {
15     pub const GUID: Guid = guid!("964e5b22-6459-11d2-8e39-00a0c969723b");
16 }
17 
18 newtype_enum! {
19     pub enum FileProtocolRevision: u64 => {
20         REVISION_1 = 0x00010000,
21         REVISION_2 = 0x00020000,
22     }
23 }
24 
25 #[derive(Debug)]
26 #[repr(C)]
27 pub struct FileProtocolV1 {
28     pub revision: FileProtocolRevision,
29     pub open: unsafe extern "efiapi" fn(
30         this: *mut Self,
31         new_handle: *mut *mut Self,
32         file_name: *const Char16,
33         open_mode: FileMode,
34         attributes: FileAttribute,
35     ) -> Status,
36     pub close: unsafe extern "efiapi" fn(this: *mut Self) -> Status,
37     pub delete: unsafe extern "efiapi" fn(this: *mut Self) -> Status,
38     pub read: unsafe extern "efiapi" fn(
39         this: *mut Self,
40         buffer_size: *mut usize,
41         buffer: *mut c_void,
42     ) -> Status,
43     pub write: unsafe extern "efiapi" fn(
44         this: *mut Self,
45         buffer_size: *mut usize,
46         buffer: *const c_void,
47     ) -> Status,
48     pub get_position: unsafe extern "efiapi" fn(this: *const Self, position: *mut u64) -> Status,
49     pub set_position: unsafe extern "efiapi" fn(this: *mut Self, position: u64) -> Status,
50     pub get_info: unsafe extern "efiapi" fn(
51         this: *mut Self,
52         information_type: *const Guid,
53         buffer_size: *mut usize,
54         buffer: *mut c_void,
55     ) -> Status,
56     pub set_info: unsafe extern "efiapi" fn(
57         this: *mut Self,
58         information_type: *const Guid,
59         buffer_size: usize,
60         buffer: *const c_void,
61     ) -> Status,
62     pub flush: unsafe extern "efiapi" fn(this: *mut Self) -> Status,
63 }
64 
65 #[derive(Debug)]
66 #[repr(C)]
67 pub struct FileProtocolV2 {
68     pub v1: FileProtocolV1,
69     pub open_ex: unsafe extern "efiapi" fn(
70         this: *mut Self,
71         new_handle: *mut *mut Self,
72         file_name: *const Char16,
73         open_mode: FileMode,
74         attributes: FileAttribute,
75         token: *mut FileIoToken,
76     ) -> Status,
77     pub read_ex: unsafe extern "efiapi" fn(this: *mut Self, token: *mut FileIoToken) -> Status,
78     pub write_ex: unsafe extern "efiapi" fn(this: *mut Self, token: *mut FileIoToken) -> Status,
79     pub flush_ex: unsafe extern "efiapi" fn(this: *mut Self, token: *mut FileIoToken) -> Status,
80 }
81 
82 #[derive(Debug)]
83 #[repr(C)]
84 pub struct FileIoToken {
85     pub event: Event,
86     pub status: Status,
87     pub buffer_size: usize,
88     pub buffer: *mut c_void,
89 }
90 
91 bitflags! {
92     /// File attributes.
93     #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
94     #[repr(transparent)]
95     pub struct FileAttribute: u64 {
96         /// The file cannot be opened for modification.
97         const READ_ONLY = 0x0000000000000001;
98 
99         /// The file is hidden from normal directory views.
100         const HIDDEN = 0x0000000000000002;
101 
102         /// The file belongs to the system and must not be physically moved.
103         const SYSTEM = 0x0000000000000004;
104 
105         /// The file is a directory.
106         const DIRECTORY = 0x0000000000000010;
107 
108         /// The file is marked for archival by backup software.
109         const ARCHIVE = 0x0000000000000020;
110 
111         /// Mask combining all the valid attributes.
112         const VALID_ATTR = 0x0000000000000037;
113     }
114 }
115 
116 bitflags! {
117     #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
118     #[repr(transparent)]
119     pub struct FileMode: u64 {
120         const READ = 0x0000000000000001;
121         const WRITE = 0x0000000000000002;
122         const CREATE = 0x8000000000000000;
123     }
124 }
125 
126 #[derive(Debug)]
127 #[repr(C)]
128 pub struct FileInfo {
129     pub size: u64,
130     pub file_size: u64,
131     pub physical_size: u64,
132     pub create_time: Time,
133     pub last_access_time: Time,
134     pub modification_time: Time,
135     pub attribute: FileAttribute,
136 
137     /// The null-terminated name of the file. For a root directory, this is an
138     /// empty string.
139     ///
140     /// Note that this field is actually a variable-length array. In order to
141     /// avoid making this struct a DST, the field is represented as a
142     /// zero-length array here.
143     pub file_name: [Char16; 0],
144 }
145 
146 impl FileInfo {
147     pub const ID: Guid = guid!("09576e92-6d3f-11d2-8e39-00a0c969723b");
148 }
149 
150 #[derive(Debug)]
151 #[repr(C)]
152 pub struct FileSystemInfo {
153     pub size: u64,
154     pub read_only: u8,
155     pub volume_size: u64,
156     pub free_space: u64,
157     pub block_size: u32,
158 
159     /// The null-terminated label of the volume.
160     ///
161     /// Note that this field is actually a variable-length array. In order to
162     /// avoid making this struct a DST, the field is represented as a
163     /// zero-length array here.
164     pub volume_label: [Char16; 0],
165 }
166 
167 impl FileSystemInfo {
168     pub const ID: Guid = guid!("09576e93-6d3f-11d2-8e39-00a0c969723b");
169 }
170 
171 #[derive(Debug)]
172 #[repr(C)]
173 pub struct FileSystemVolumeLabel {
174     /// The null-terminated label of the volume.
175     ///
176     /// Note that this field is actually a variable-length array. In order to
177     /// avoid making this struct a DST, the field is represented as a
178     /// zero-length array here.
179     pub volume_label: [Char16; 0],
180 }
181 
182 impl FileSystemVolumeLabel {
183     pub const ID: Guid = guid!("db47d7d3-fe81-11d3-9a35-0090273fc14d");
184 }
185