VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/HostDriveImpl.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1/* $Id: HostDriveImpl.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VirtualBox Main - IHostDrive implementation, VBoxSVC.
4 */
5
6/*
7 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define LOG_GROUP LOG_GROUP_MAIN_HOSTDRIVE
29#include "Global.h"
30#include "HostDriveImpl.h"
31#include "HostDrivePartitionImpl.h"
32#include "LoggingNew.h"
33#include "VirtualBoxImpl.h"
34
35#include <iprt/dvm.h>
36#include <iprt/err.h>
37#include <iprt/file.h>
38#include <iprt/path.h>
39#include <iprt/vfs.h>
40#include <VBox/com/Guid.h>
41
42
43/*
44 * HostDrive implementation.
45 */
46DEFINE_EMPTY_CTOR_DTOR(HostDrive)
47
48HRESULT HostDrive::FinalConstruct()
49{
50 return BaseFinalConstruct();
51}
52
53void HostDrive::FinalRelease()
54{
55 uninit();
56
57 BaseFinalRelease();
58}
59
60/**
61 * Initializes the instance.
62 */
63HRESULT HostDrive::initFromPathAndModel(const com::Utf8Str &drivePath, const com::Utf8Str &driveModel)
64{
65 LogFlowThisFunc(("\n"));
66
67 AssertReturn(!drivePath.isEmpty(), E_INVALIDARG);
68
69 /* Enclose the state transition NotReady->InInit->Ready */
70 AutoInitSpan autoInitSpan(this);
71 AssertReturn(autoInitSpan.isOk(), E_FAIL);
72
73 m.partitioningType = PartitioningType_MBR;
74 m.drivePath = drivePath;
75 m.model = driveModel;
76 m.partitions.clear();
77
78 /*
79 * Try open the drive so we can extract futher details,
80 * like the size, sector size and partitions.
81 */
82 HRESULT hrc = E_FAIL;
83 RTFILE hRawFile = NIL_RTFILE;
84 int vrc = RTFileOpen(&hRawFile, drivePath.c_str(), RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
85 if (RT_SUCCESS(vrc))
86 {
87 vrc = RTFileQuerySize(hRawFile, &m.cbDisk);
88 int vrc2 = RTFileQuerySectorSize(hRawFile, &m.cbSector);
89 if (RT_FAILURE(vrc2))
90 vrc = vrc2;
91 if (RT_SUCCESS(vrc))
92 {
93 /*
94 * Hand it to DVM.
95 */
96 RTVFSFILE hVfsFile = NIL_RTVFSFILE;
97 vrc = RTVfsFileFromRTFile(hRawFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE /*fOpen*/,
98 true /*fLeaveOpen*/, &hVfsFile);
99 if (RT_SUCCESS(vrc))
100 {
101 RTDVM hVolMgr = NIL_RTDVM;
102 vrc = RTDvmCreate(&hVolMgr, hVfsFile, m.cbSector, 0 /*fFlags*/);
103 if (RT_SUCCESS(vrc))
104 {
105 vrc = RTDvmMapOpen(hVolMgr);
106 if (RT_SUCCESS(vrc))
107 {
108 hrc = S_OK;
109
110 /*
111 * Get details.
112 */
113 switch (RTDvmMapGetFormatType(hVolMgr))
114 {
115 case RTDVMFORMATTYPE_GPT:
116 m.partitioningType = PartitioningType_GPT;
117 break;
118 case RTDVMFORMATTYPE_MBR:
119 m.partitioningType = PartitioningType_MBR;
120 break;
121 case RTDVMFORMATTYPE_BSD_LABEL:
122 AssertMsgFailed(("TODO\n"));
123 break;
124 default:
125 AssertFailed();
126 }
127
128 RTUUID Uuid = RTUUID_INITIALIZE_NULL;
129 if (RT_SUCCESS(RTDvmMapQueryDiskUuid(hVolMgr, &Uuid)))
130 m.uuid = Uuid;
131
132 /*
133 * Enumerate volumes and tuck them into the partitions list..
134 */
135 uint32_t const cVolumes = RTDvmMapGetValidVolumes(hVolMgr);
136 RTDVMVOLUME hVol = NIL_RTDVMVOLUME;
137 for (uint32_t i = 0; i < cVolumes; i++)
138 {
139 /* Enumeration cruft: */
140 RTDVMVOLUME hVolNext = NIL_RTDVMVOLUME;
141 if (i == 0)
142 vrc = RTDvmMapQueryFirstVolume(hVolMgr, &hVolNext);
143 else
144 vrc = RTDvmMapQueryNextVolume(hVolMgr, hVol, &hVolNext);
145 AssertRCBreakStmt(vrc, hrc = Global::vboxStatusCodeToCOM(vrc));
146
147 uint32_t cRefs = RTDvmVolumeRelease(hVol);
148 Assert(cRefs != UINT32_MAX); RT_NOREF(cRefs);
149 hVol = hVolNext;
150
151 /* Instantiate a new partition object and add it to the list: */
152 ComObjPtr<HostDrivePartition> ptrHostPartition;
153 hrc = ptrHostPartition.createObject();
154 if (SUCCEEDED(hrc))
155 hrc = ptrHostPartition->initFromDvmVol(hVol);
156 if (SUCCEEDED(hrc))
157 try
158 {
159 m.partitions.push_back(ptrHostPartition);
160 }
161 catch (std::bad_alloc &)
162 {
163 AssertFailedBreakStmt(hrc = E_OUTOFMEMORY);
164 }
165 }
166 RTDvmVolumeRelease(hVol);
167 }
168 else
169 hrc = Global::vboxStatusCodeToCOM(vrc);
170 RTDvmRelease(hVolMgr);
171 }
172 else
173 hrc = Global::vboxStatusCodeToCOM(vrc);
174 RTVfsFileRelease(hVfsFile);
175 }
176 else
177 hrc = Global::vboxStatusCodeToCOM(vrc);
178 }
179 else /* VERR_IO_NOT_READ / STATUS_NO_MEDIA_IN_DEVICE is likely for card readers on windows. */
180 hrc = Global::vboxStatusCodeToCOM(vrc);
181 RTFileClose(hRawFile);
182 }
183 else
184 {
185 /*
186 * We don't use the Global::vboxStatusCodeToCOM(vrc) here
187 * because RTFileOpen can return some error which causes
188 * the assertion and breaks original idea of returning
189 * the object in the limited state.
190 */
191 if ( vrc == VERR_RESOURCE_BUSY
192 || vrc == VERR_ACCESS_DENIED)
193 hrc = E_ACCESSDENIED;
194 else
195 hrc = VBOX_E_IPRT_ERROR;
196 }
197
198 /* Confirm a successful initialization */
199 if (SUCCEEDED(hrc))
200 autoInitSpan.setSucceeded();
201 else
202 autoInitSpan.setLimited(hrc);
203 return S_OK;
204}
205
206/**
207 * Uninitializes the instance.
208 * Called either from FinalRelease() or by the parent when it gets destroyed.
209 */
210void HostDrive::uninit()
211{
212 LogFlowThisFunc(("\n"));
213
214 /* Enclose the state transition Ready->InUninit->NotReady */
215 AutoUninitSpan autoUninitSpan(this);
216 if (autoUninitSpan.uninitDone())
217 return;
218
219 m.drivePath.setNull();
220 m.partitions.clear();
221}
222
223
224/*********************************************************************************************************************************
225* IHostDrive properties *
226*********************************************************************************************************************************/
227
228HRESULT HostDrive::getPartitioningType(PartitioningType_T *aPartitioningType)
229{
230 *aPartitioningType = m.partitioningType;
231 return S_OK;
232}
233
234HRESULT HostDrive::getDrivePath(com::Utf8Str &aDrivePath)
235{
236 aDrivePath = m.drivePath;
237 return S_OK;
238}
239
240HRESULT HostDrive::getUuid(com::Guid &aUuid)
241{
242 aUuid = m.uuid;
243 return S_OK;
244}
245
246HRESULT HostDrive::getSectorSize(ULONG *aSectorSize)
247{
248 *aSectorSize = m.cbSector;
249 return S_OK;
250}
251
252HRESULT HostDrive::getSize(LONG64 *aSize)
253{
254 *aSize = (LONG64)m.cbDisk;
255 if (*aSize < 0)
256 *aSize = INT64_MAX;
257 return S_OK;
258}
259
260HRESULT HostDrive::getModel(com::Utf8Str &aModel)
261{
262 return aModel.assignEx(m.model);
263}
264
265HRESULT HostDrive::getPartitions(std::vector<ComPtr<IHostDrivePartition> > &aPartitions)
266{
267 aPartitions = m.partitions;
268 return S_OK;
269}
270
271
272
273/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use