vfs: check userland buffers before reading them.
[haiku.git] / src / system / libroot / os / disk_scanner.cpp
blob2184f7e56df0a8a2ff44392359f9001511831eb6
1 //----------------------------------------------------------------------
2 // This software is part of the OpenBeOS distribution and is covered
3 // by the MIT License.
4 //---------------------------------------------------------------------
6 #include <disk_scanner.h>
7 #include <disk_scanner/disk_scanner.h>
8 #include <KernelExport.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <string.h>
15 // get_nth_session_info
16 /*! \brief Retrieves information about a session on a device.
17 \param deviceFD File descriptor for the device in question.
18 \param index The session index.
19 \param sessionInfo Pointer to a pre-allocated session_info to be filled
20 out by the function.
21 \return
22 - \c B_OK: Everything went fine.
23 - an error code: The contents of \a sessionInfo is undefined.
25 status_t
26 get_nth_session_info(int deviceFD, int32 index, session_info *sessionInfo)
28 status_t error = (sessionInfo ? B_OK : B_BAD_VALUE);
29 disk_scanner_module_info *diskScanner = NULL;
30 // get the disk scanner module
31 if (error == B_OK) {
32 error = get_module(DISK_SCANNER_MODULE_NAME,
33 (module_info**)&diskScanner);
35 // get the session info
36 if (error == B_OK) {
37 error = diskScanner->get_nth_session_info(deviceFD, index,
38 sessionInfo, NULL);
40 // put the partition scanner module
41 if (diskScanner)
42 put_module(diskScanner->module.name);
43 return error;
46 // get_nth_partition_info
47 /*! \brief Retrieves information about a partition on a device.
49 The fields \c device and \c mounted_at of \a partitionInfo are not set.
51 \param deviceFD File descriptor for the device in question.
52 \param sessionIndex The index of the session on which the partition
53 resides.
54 \param partitionIndex The partition index.
55 \param partitionInfo Pointer to a pre-allocated extended_partition_info
56 to be filled out by the function.
57 \param partitionMapName Pointer to a pre-allocated char buffer of minimal
58 size \c B_FILE_NAME_LENGTH, into which the short name of the
59 partitioning system shall be written. The result is the empty
60 string (""), if no partitioning system is used (e.g. for floppies).
61 May be \c NULL.
62 \return
63 - \c B_OK: Everything went fine.
64 - an error code: The contents of \a partitionInfo is undefined.
66 status_t
67 get_nth_partition_info(int deviceFD, int32 sessionIndex, int32 partitionIndex,
68 extended_partition_info *partitionInfo,
69 char *partitionMapName)
71 if (partitionInfo == NULL)
72 return B_BAD_VALUE;
74 session_info sessionInfo;
75 disk_scanner_module_info *diskScanner = NULL;
77 // get the disk scanner module
78 status_t error = get_module(DISK_SCANNER_MODULE_NAME,
79 (module_info**)&diskScanner);
80 if (diskScanner == NULL)
81 return error;
83 // get the session info
84 error = diskScanner->get_nth_session_info(deviceFD, sessionIndex,
85 &sessionInfo, NULL);
87 // get the partition info
88 if (error == B_OK) {
89 partitionInfo->info.logical_block_size
90 = sessionInfo.logical_block_size;
91 partitionInfo->info.session = sessionIndex;
92 partitionInfo->info.partition = partitionIndex;
93 // NOTE: partitionInfo->info.device is not filled in!
94 // The user can this info via B_GET_PARTITION_INFO. We could get the dir
95 // of the raw device and construct the partition device name with session and
96 // partition ID.
97 // Update: No, we can neither get the name of the raw device nor of the
98 // directory it lives in. We only have a FD and I see no way to get a path
99 // from it. Since deviceFD might represent an image file, we can't even get
100 // the its path by recursively searching the /dev/disk directory.
101 partitionInfo->info.device[0] = '\0';
102 error = diskScanner->get_nth_partition_info(deviceFD, &sessionInfo,
103 partitionIndex, partitionInfo, partitionMapName, NULL);
105 // get the FS info
106 if (error == B_OK) {
107 bool hidden = (partitionInfo->flags & B_HIDDEN_PARTITION);
108 if (!hidden) {
109 error = diskScanner->get_partition_fs_info(deviceFD,
110 partitionInfo);
112 // in case the partition is no data partition or the FS is unknown,
113 // we fill in the respective fields
114 if (hidden || error == B_ENTRY_NOT_FOUND) {
115 error = B_OK;
116 partitionInfo->file_system_short_name[0] = '\0';
117 partitionInfo->file_system_long_name[0] = '\0';
118 partitionInfo->volume_name[0] = '\0';
119 // partitionInfo->mounted_at[0] = '\0';
120 partitionInfo->file_system_flags = 0;
122 // NOTE: Where do we get mounted_at from?
123 // Update: Actually, it looks, like it is really hard. We could traverse the
124 // list of mounted devices, build for each one the raw device path from its
125 // partition device path, check, if the raw device is the same one as deviceFD.
126 // Then, with the path of the raw device we have more options.
128 // put the partition scanner module
129 if (diskScanner)
130 put_module(diskScanner->module.name);
131 return error;
134 // get_partitioning_parameters
135 /*! \brief Returns parameters for partitioning a session.
137 The partitioning system (module) identified by \a identifier is asked to
138 return parameters for the session. If the session is already partitioned
139 using this system, then the parameters describing the current layout will
140 be returned, otherwise default values.
142 If the supplied buffer is too small for the parameters, the function
143 returns \c B_OK, but doesn't fill in the buffer; the required buffer
144 size is returned in \a actualSize. If the buffer is large enough,
145 \a actualSize is set to the actually used size. The size includes the
146 terminating null.
148 \param deviceFD The device the session to be partitioned resides on.
149 \param sessionIndex The index of the session to be partitioned.
150 \param identifier A string identifying the partitioning system to be used.
151 \param buffer Pointer to a pre-allocated buffer of size \a bufferSize.
152 \param bufferSize The size of \a buffer.
153 \param actualSize Pointer to a pre-allocated size_t to be set to the
154 actually needed buffer size.
155 \return
156 - \c B_OK: The parameters could be retrieved or the buffer is too
157 small. \a actualSize has to be checked!
158 - another error code, if something went wrong
160 status_t
161 get_partitioning_parameters(int deviceFD, int32 sessionIndex,
162 const char *identifier, char *buffer,
163 size_t bufferSize, size_t *actualSize)
165 status_t error = (identifier && buffer && actualSize ? B_OK : B_BAD_VALUE);
166 disk_scanner_module_info *diskScanner = NULL;
167 session_info sessionInfo;
168 // get the disk scanner module
169 if (error == B_OK) {
170 error = get_module(DISK_SCANNER_MODULE_NAME,
171 (module_info**)&diskScanner);
173 // get the session info
174 if (error == B_OK) {
175 error = diskScanner->get_nth_session_info(deviceFD, sessionIndex,
176 &sessionInfo, NULL);
178 // get the parameters
179 if (error == B_OK) {
180 error = diskScanner->get_partitioning_params(deviceFD, &sessionInfo,
181 identifier, buffer, bufferSize, actualSize);
183 // put the partition scanner module
184 if (diskScanner)
185 put_module(diskScanner->module.name);
186 return error;
189 // get_fs_initialization_parameters
190 /*! \brief Returns parameters for initializing a volume.
192 The FS identified by \a fileSystem is asked to return parameters for
193 the volume. If the volume is already initialized with this FS, then the
194 parameters describing the current state will be returned, otherwise
195 default values.
197 If the supplied buffer is too small for the parameters, the function
198 returns \c B_OK, but doesn't fill in the buffer; the required buffer
199 size is returned in \a actualSize. If the buffer is large enough,
200 \a actualSize is set to the actually used size. The size includes the
201 terminating null.
203 \param deviceFD The device the partition to be initialized resides on.
204 \param sessionIndex The index of the session the partition to be
205 initialized resides on.
206 \param partitionIndex The index of the partition to be initialized.
207 \param fileSystem A string identifying the file system to be used.
208 \param buffer Pointer to a pre-allocated buffer of size \a bufferSize.
209 \param bufferSize The size of \a buffer.
210 \param actualSize Pointer to a pre-allocated size_t to be set to the
211 actually needed buffer size.
212 \return
213 - \c B_OK: The parameters could be retrieved or the buffer is too
214 small. \a actualSize has to be checked!
215 - another error code, if something went wrong
217 status_t
218 get_fs_initialization_parameters(int deviceFD, int32 sessionIndex,
219 int32 partitionIndex, const char *fileSystem,
220 char *buffer, size_t bufferSize,
221 size_t *actualSize)
223 // not yet implemented
224 return B_UNSUPPORTED;
227 // partition_session
228 /*! \brief Partitions a specified session on a device using the paritioning
229 system identified by \a identifier and according to supplied
230 parameters.
231 \param deviceFD The device the session to be partitioned resides on.
232 \param sessionIndex The index of the session to be partitioned.
233 \param identifier A string identifying the partitioning system to be used.
234 \param parameters Parameters according to which the session shall be
235 partitioned. May be \c NULL, depending on the concerned partition
236 module.
237 \return \c B_OK, if everything went fine, an error code otherwise.
239 status_t
240 partition_session(int deviceFD, int32 sessionIndex, const char *identifier,
241 const char *parameters)
243 status_t error = (identifier ? B_OK : B_BAD_VALUE);
244 disk_scanner_module_info *diskScanner = NULL;
245 session_info sessionInfo;
246 // get the disk scanner module
247 if (error == B_OK) {
248 error = get_module(DISK_SCANNER_MODULE_NAME,
249 (module_info**)&diskScanner);
251 // get the session info
252 if (error == B_OK) {
253 error = diskScanner->get_nth_session_info(deviceFD, sessionIndex,
254 &sessionInfo, NULL);
256 // partition the session
257 if (error == B_OK) {
258 error = diskScanner->partition(deviceFD, &sessionInfo, identifier,
259 parameters);
261 // put the partition scanner module
262 if (diskScanner)
263 put_module(diskScanner->module.name);
264 return error;
267 // initialize_volume
268 /*! \brief Initializes a specified device using a certain file system.
269 \param where The path to the device to be initialized.
270 \param fileSystem The identifier of the file system to be used for that
271 partition.
272 \param volumeName The name to be given to the initialized volume.
273 \param parameters Parameters according to which the session shall be
274 initialized.
275 \return \c B_OK, if everything went fine, an error code otherwise.
277 status_t
278 initialize_volume(const char *where, const char *fileSystem,
279 const char *volumeName, const char *parameters)
281 // not yet implemented
282 return B_UNSUPPORTED;