VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/testcase/vhddtool.cpp@ 61

Last change on this file since 61 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1/** @file
2 *
3 * VBox HDD container maintenance/conversion utility
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25#include <VBox/VBoxHDD.h>
26#include <iprt/alloc.h>
27#include <iprt/file.h>
28#include <iprt/stream.h>
29#include <iprt/string.h>
30#include <iprt/runtime.h>
31#include <VBox/err.h>
32
33
34
35static void ascii2upper(char *psz)
36{
37 for (;*psz; psz++)
38 if (*psz >= 'a' && *psz <= 'z')
39 *psz += 'A' - 'z';
40}
41
42static int UsageExit()
43{
44 RTPrintf("Usage: vditool <Command> [Params]\n" \
45 "Commands and params:\n" \
46 " NEW Filename Mbytes - create new image;\n" \
47 " DD Filename DDFilename - create new image from DD format image;\n" \
48 " CONVERT Filename - convert VDI image from old format;\n" \
49 " DUMP Filename - debug dump;\n" \
50 " RESETGEO Filename - reset geometry information;\n" \
51 " COPY FromImage ToImage - make image copy;\n" \
52 " COPYDD FromImage DDFilename - make a DD copy of the image;\n" \
53 " SHRINK Filename - optimize (reduce) VDI image size.\n");
54 return 1;
55}
56
57static int SyntaxError(const char *pszMsg)
58{
59 RTPrintf("Syntax error: %s\n\n", pszMsg);
60 UsageExit();
61 return 1;
62}
63
64/**
65 * Prints a done message indicating success or failure.
66 * @returns rc
67 * @param rc Status code.
68 */
69static int PrintDone(int rc)
70{
71 if (rc == VINF_SUCCESS)
72 RTPrintf("The operation completed successfully!\n");
73 else if (VBOX_SUCCESS(rc))
74 RTPrintf("The operation completed successfully! (rc=%Rrc)\n", rc);
75 else
76 RTPrintf("failure: %Rrf (%Rrc)\n", rc, rc);
77 return rc;
78}
79
80static int NewImage(const char *pszFilename, uint32_t cMBs)
81{
82 RTPrintf("creating VDI: file=\"%s\" size=%u MB...\n",
83 pszFilename, cMBs);
84 int rc = VDICreateBaseImage(pszFilename,
85 VDI_IMAGE_TYPE_NORMAL,
86 (uint64_t)cMBs * (uint64_t)(1024 * 1024),
87 "Newly created test image", NULL, NULL);
88 return PrintDone(rc);
89}
90
91static int ConvertDDImage(const char *pszFilename, const char *pszDDFilename)
92{
93 RTPrintf("converting VDI: from DD image file=\"%s\" to file=\"%s\"...\n",
94 pszDDFilename, pszFilename);
95
96 /* open raw image file. */
97 RTFILE File;
98 int rc = RTFileOpen(&File, pszDDFilename, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
99 if (VBOX_FAILURE(rc))
100 {
101 RTPrintf("File=\"%s\" open error: %Rrf\n", pszDDFilename, rc);
102 return rc;
103 }
104
105 /* get image size. */
106 uint64_t cbFile;
107 rc = RTFileGetSize(File, &cbFile);
108 if (VBOX_SUCCESS(rc))
109 {
110 RTPrintf("creating fixed image with size %u Bytes...\n", (unsigned)cbFile);
111 rc = VDICreateBaseImage(pszFilename,
112 VDI_IMAGE_TYPE_FIXED,
113 cbFile,
114 "Converted from DD test image", NULL, NULL);
115 PrintDone(rc);
116 if (VBOX_SUCCESS(rc))
117 {
118 RTPrintf("writing data...\n");
119 PVDIDISK pVdi = VDIDiskCreate();
120 rc = VDIDiskOpenImage(pVdi, pszFilename, VDI_OPEN_FLAGS_NORMAL);
121 if (VBOX_SUCCESS(rc))
122 {
123 /* alloc work buffer. */
124 void *pvBuf = RTMemAlloc(VDIDiskGetBufferSize(pVdi));
125 if (pvBuf)
126 {
127 uint64_t off = 0;
128 while (off < cbFile)
129 {
130 unsigned cbRead = 0;
131 rc = RTFileRead(File, pvBuf, VDIDiskGetBufferSize(pVdi), &cbRead);
132 if (VBOX_FAILURE(rc) || !cbRead)
133 break;
134 rc = VDIDiskWrite(pVdi, off, pvBuf, cbRead);
135 if (VBOX_FAILURE(rc))
136 break;
137 off += cbRead;
138 }
139
140 RTMemFree(pvBuf);
141 }
142 else
143 rc = VERR_NO_MEMORY;
144
145 VDIDiskCloseImage(pVdi);
146 }
147
148 if (VBOX_FAILURE(rc))
149 {
150 /* delete image on error */
151 VDIDeleteImage(pszFilename);
152 }
153 PrintDone(rc);
154 }
155 }
156 RTFileClose(File);
157
158 return rc;
159}
160
161static DECLCALLBACK(int) ProcessCallback(PVM pVM, unsigned uPercent, void *pvUser)
162{
163 unsigned *pPercent = (unsigned *)pvUser;
164
165 if (*pPercent != uPercent)
166 {
167 *pPercent = uPercent;
168 RTPrintf(".");
169 if ((uPercent % 10) == 0 && uPercent)
170 RTPrintf("%d%%", uPercent);
171 RTStrmFlush(g_pStdOut);
172 }
173
174 return VINF_SUCCESS;
175}
176
177static int ConvertOldImage(const char *pszFilename)
178{
179 RTPrintf("converting VDI image file=\"%s\" to a new format...\n"
180 "progress: 0%%",
181 pszFilename);
182 unsigned uPercent = 0;
183 int rc = VDIConvertImage(pszFilename, ProcessCallback, &uPercent);
184 RTPrintf("\n");
185 return PrintDone(rc);
186}
187
188static int DumpImage(const char *pszFilename)
189{
190 RTPrintf("dumping VDI image file=\"%s\" into the log file...\n", pszFilename);
191 PVDIDISK pVdi = VDIDiskCreate();
192 int rc = VDIDiskOpenImage(pVdi, pszFilename, VDI_OPEN_FLAGS_READONLY);
193 if (VBOX_SUCCESS(rc))
194 {
195 VDIDiskDumpImages(pVdi);
196 VDIDiskCloseAllImages(pVdi);
197 }
198 return PrintDone(rc);
199}
200
201static int ResetImageGeometry(const char *pszFilename)
202{
203 RTPrintf("resetting geometry info of VDI image file=\"%s\"\n", pszFilename);
204 PVDIDISK pVdi = VDIDiskCreate();
205 int rc = VDIDiskOpenImage(pVdi, pszFilename, VDI_OPEN_FLAGS_NORMAL);
206 if (VBOX_SUCCESS(rc))
207 {
208 rc = VDIDiskSetGeometry(pVdi, 0, 0, 0);
209 if (VBOX_SUCCESS(rc))
210 rc = VDIDiskSetTranslation(pVdi, PDMBIOSTRANSLATION_AUTO);
211 }
212 VDIDiskCloseImage(pVdi);
213 return PrintDone(rc);
214}
215
216static int CopyImage(const char *pszDstFile, const char *pszSrcFile)
217{
218 RTPrintf("copying VDI image file=\"%s\" to image file=\"%s\"...\n"
219 "progress: 0%%",
220 pszSrcFile, pszDstFile);
221 unsigned uPrecent = 0;
222 int rc = VDICopyImage(pszDstFile, pszSrcFile, NULL, ProcessCallback, &uPrecent);
223 RTPrintf("\n");
224 return PrintDone(rc);
225}
226
227static int CopyToDD(const char *pszDstFile, const char *pszSrcFile)
228{
229 RTPrintf("copying VDI image file=\"%s\" to DD file=\"%s\"...\n",
230 pszSrcFile, pszDstFile);
231 PVDIDISK pVdi = VDIDiskCreate();
232 int rc = VDIDiskOpenImage(pVdi, pszSrcFile, VDI_OPEN_FLAGS_NORMAL);
233 if (VBOX_SUCCESS(rc))
234 {
235 RTFILE FileDst;
236 rc = RTFileOpen(&FileDst, pszDstFile, RTFILE_O_CREATE | RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE);
237 if (VBOX_SUCCESS(rc))
238 {
239 uint64_t cbSrc = VDIDiskGetSize(pVdi);
240 const unsigned cbBuf = VDIDiskGetBlockSize(pVdi); /* or perhaps VDIDiskGetBufferSize(pVdi)? */
241 void *pvBuf = RTMemAlloc(cbBuf);
242 if (pvBuf)
243 {
244 uint64_t off = 0;
245 while (off < cbSrc)
246 {
247 rc = VDIDiskRead(pVdi, off, pvBuf, cbBuf);
248 if (VBOX_FAILURE(rc))
249 break;
250 rc = RTFileWrite(FileDst, pvBuf, cbBuf, NULL);
251 if (VBOX_FAILURE(rc))
252 break;
253 off += cbBuf;
254 }
255 RTMemFree(pvBuf);
256 }
257 RTFileClose(FileDst);
258 }
259 }
260 VDIDiskCloseImage(pVdi);
261 return PrintDone(rc);
262}
263
264static int ShrinkImage(const char *pszFilename)
265{
266 RTPrintf("shrinking VDI image file=\"%s\"...\n"
267 "progress: 0%%",
268 pszFilename);
269 unsigned uPrecent;
270 int rc = VDIShrinkImage(pszFilename, ProcessCallback, &uPrecent);
271 RTPrintf("\n");
272 return PrintDone(rc);
273}
274
275int main(int argc, char **argv)
276{
277 RTR3Init();
278 RTPrintf("vditool Copyright (c) 2004-2005 InnoTek Systemberatung GmbH.\n\n");
279
280 /*
281 * Do cmd line parsing.
282 */
283 if (argc < 2)
284 return UsageExit();
285
286 char szCmd[16];
287 if (strlen(argv[1]) >= sizeof(szCmd))
288 return SyntaxError("Invalid command!");
289 strcpy(szCmd, argv[1]);
290 ascii2upper(szCmd);
291
292 int rc;
293 if (strcmp(szCmd, "NEW") == 0)
294 {
295 if (argc != 4)
296 return SyntaxError("Invalid argument count!");
297
298 uint32_t cMBs;
299 rc = RTStrToUInt32Ex(argv[3], NULL, 10, &cMBs);
300 if (VBOX_FAILURE(rc))
301 return SyntaxError("Invalid number!");
302 if ( cMBs < 2
303 || cMBs > 1024*1024)
304 {
305 RTPrintf("error: Disk size %RU32 (MB) is not within the range %u-%u!\n",
306 cMBs, 2, 1024*1024);
307 return 1;
308 }
309
310 rc = NewImage(argv[2], cMBs);
311 }
312 else if (strcmp(szCmd, "DD") == 0)
313 {
314 if (argc != 4)
315 return SyntaxError("Invalid argument count!");
316 rc = ConvertDDImage(argv[2], argv[3]);
317 }
318 else if (strcmp(szCmd, "CONVERT") == 0)
319 {
320 if (argc != 3)
321 return SyntaxError("Invalid argument count!");
322 rc = ConvertOldImage(argv[2]);
323 }
324 else if (strcmp(szCmd, "DUMP") == 0)
325 {
326 if (argc != 3)
327 return SyntaxError("Invalid argument count!");
328 rc = DumpImage(argv[2]);
329 }
330 else if (strcmp(szCmd, "RESETGEO") == 0)
331 {
332 if (argc != 3)
333 return SyntaxError("Invalid argument count!");
334 rc = ResetImageGeometry(argv[2]);
335 }
336 else if (strcmp(szCmd, "COPY") == 0)
337 {
338 if (argc != 4)
339 return SyntaxError("Invalid argument count!");
340 rc = CopyImage(argv[3], argv[2]);
341 }
342 else if (strcmp(szCmd, "COPYDD") == 0)
343 {
344 if (argc != 4)
345 return SyntaxError("Invalid argument count!");
346 rc = CopyToDD(argv[3], argv[2]);
347 }
348 else if (strcmp(szCmd, "SHRINK") == 0)
349 {
350 if (argc != 3)
351 return SyntaxError("Invalid argument count!");
352 rc = ShrinkImage(argv[2]);
353 }
354 else
355 return SyntaxError("Invalid command!");
356
357 return !VBOX_SUCCESS(rc);
358}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette