VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp@ 16024

Last change on this file since 16024 was 15693, checked in by vboxsync, 16 years ago

VBoxManage converttoraw: forgotten default format

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.7 KB
Line 
1/* $Id: VBoxManageDisk.cpp 15693 2008-12-19 14:04:04Z vboxsync $ */
2/** @file
3 * VBoxManage - The disk delated commands.
4 */
5
6/*
7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
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 (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef VBOX_ONLY_DOCS
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#include <VBox/com/com.h>
28#include <VBox/com/array.h>
29#include <VBox/com/ErrorInfo.h>
30#include <VBox/com/VirtualBox.h>
31
32#include <iprt/asm.h>
33#include <iprt/file.h>
34#include <iprt/stream.h>
35#include <iprt/string.h>
36#include <VBox/log.h>
37#include <VBox/VBoxHDD-new.h>
38
39#include "VBoxManage.h"
40using namespace com;
41
42
43// funcs
44///////////////////////////////////////////////////////////////////////////////
45
46
47static DECLCALLBACK(void) handleVDError(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
48{
49 RTPrintf("ERROR: ");
50 RTPrintfV(pszFormat, va);
51 RTPrintf("\n");
52 RTPrintf("Error code %Rrc at %s(%u) in function %s\n", rc, RT_SRC_POS_ARGS);
53}
54
55
56int handleCreateHardDisk(int argc, char *argv[],
57 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
58{
59 HRESULT rc;
60 Bstr filename;
61 uint64_t sizeMB = 0;
62 Bstr format = "VDI";
63 bool fStatic = false;
64 Bstr comment;
65 bool fRegister = false;
66 const char *type = "normal";
67
68 /* let's have a closer look at the arguments */
69 for (int i = 0; i < argc; i++)
70 {
71 if (strcmp(argv[i], "-filename") == 0)
72 {
73 if (argc <= i + 1)
74 return errorArgument("Missing argument to '%s'", argv[i]);
75 i++;
76 filename = argv[i];
77 }
78 else if (strcmp(argv[i], "-size") == 0)
79 {
80 if (argc <= i + 1)
81 return errorArgument("Missing argument to '%s'", argv[i]);
82 i++;
83 sizeMB = RTStrToUInt64(argv[i]);
84 }
85 else if (strcmp(argv[i], "-format") == 0)
86 {
87 if (argc <= i + 1)
88 return errorArgument("Missing argument to '%s'", argv[i]);
89 i++;
90 format = argv[i];
91 }
92 else if (strcmp(argv[i], "-static") == 0)
93 {
94 fStatic = true;
95 }
96 else if (strcmp(argv[i], "-comment") == 0)
97 {
98 if (argc <= i + 1)
99 return errorArgument("Missing argument to '%s'", argv[i]);
100 i++;
101 comment = argv[i];
102 }
103 else if (strcmp(argv[i], "-register") == 0)
104 {
105 fRegister = true;
106 }
107 else if (strcmp(argv[i], "-type") == 0)
108 {
109 if (argc <= i + 1)
110 return errorArgument("Missing argument to '%s'", argv[i]);
111 i++;
112 type = argv[i];
113 }
114 else
115 return errorSyntax(USAGE_CREATEHD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
116 }
117 /* check the outcome */
118 if (!filename || (sizeMB == 0))
119 return errorSyntax(USAGE_CREATEHD, "Parameters -filename and -size are required");
120
121 if (strcmp(type, "normal") && strcmp(type, "writethrough"))
122 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());
123
124 ComPtr<IHardDisk2> hardDisk;
125 CHECK_ERROR(virtualBox, CreateHardDisk2(format, filename, hardDisk.asOutParam()));
126 if (SUCCEEDED(rc) && hardDisk)
127 {
128 /* we will close the hard disk after the storage has been successfully
129 * created unless fRegister is set */
130 bool doClose = false;
131
132 if (!comment.isNull())
133 {
134 CHECK_ERROR(hardDisk,COMSETTER(Description)(comment));
135 }
136 ComPtr<IProgress> progress;
137 if (fStatic)
138 {
139 CHECK_ERROR(hardDisk, CreateFixedStorage(sizeMB, progress.asOutParam()));
140 }
141 else
142 {
143 CHECK_ERROR(hardDisk, CreateDynamicStorage(sizeMB, progress.asOutParam()));
144 }
145 if (SUCCEEDED(rc) && progress)
146 {
147 if (fStatic)
148 showProgress(progress);
149 else
150 CHECK_ERROR(progress, WaitForCompletion(-1));
151 if (SUCCEEDED(rc))
152 {
153 progress->COMGETTER(ResultCode)(&rc);
154 if (FAILED(rc))
155 {
156 com::ProgressErrorInfo info(progress);
157 if (info.isBasicAvailable())
158 RTPrintf("Error: failed to create hard disk. Error message: %lS\n", info.getText().raw());
159 else
160 RTPrintf("Error: failed to create hard disk. No error message available!\n");
161 }
162 else
163 {
164 doClose = !fRegister;
165
166 Guid uuid;
167 CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam()));
168
169 if (strcmp(type, "normal") == 0)
170 {
171 /* nothing required, default */
172 }
173 else if (strcmp(type, "writethrough") == 0)
174 {
175 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
176 }
177
178 RTPrintf("Disk image created. UUID: %s\n", uuid.toString().raw());
179 }
180 }
181 }
182 if (doClose)
183 {
184 CHECK_ERROR(hardDisk, Close());
185 }
186 }
187 return SUCCEEDED(rc) ? 0 : 1;
188}
189
190#if 0 /* disabled until disk shrinking is implemented based on VBoxHDD-new */
191static DECLCALLBACK(int) hardDiskProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
192{
193 unsigned *pPercent = (unsigned *)pvUser;
194
195 if (*pPercent != uPercent)
196 {
197 *pPercent = uPercent;
198 RTPrintf(".");
199 if ((uPercent % 10) == 0 && uPercent)
200 RTPrintf("%d%%", uPercent);
201 RTStrmFlush(g_pStdOut);
202 }
203
204 return VINF_SUCCESS;
205}
206#endif
207
208
209int handleModifyHardDisk(int argc, char *argv[],
210 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
211{
212 HRESULT rc;
213
214 /* The uuid/filename and a command */
215 if (argc < 2)
216 return errorSyntax(USAGE_MODIFYHD, "Incorrect number of parameters");
217
218 ComPtr<IHardDisk2> hardDisk;
219 Bstr filepath;
220
221 /* first guess is that it's a UUID */
222 Guid uuid(argv[0]);
223 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
224 /* no? then it must be a filename */
225 if (!hardDisk)
226 {
227 filepath = argv[0];
228 CHECK_ERROR(virtualBox, FindHardDisk2(filepath, hardDisk.asOutParam()));
229 }
230
231 /* let's find out which command */
232 if (strcmp(argv[1], "settype") == 0)
233 {
234 /* hard disk must be registered */
235 if (SUCCEEDED(rc) && hardDisk)
236 {
237 char *type = NULL;
238
239 if (argc <= 2)
240 return errorArgument("Missing argument to for settype");
241
242 type = argv[2];
243
244 HardDiskType_T hddType;
245 CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));
246
247 if (strcmp(type, "normal") == 0)
248 {
249 if (hddType != HardDiskType_Normal)
250 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));
251 }
252 else if (strcmp(type, "writethrough") == 0)
253 {
254 if (hddType != HardDiskType_Writethrough)
255 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
256
257 }
258 else if (strcmp(type, "immutable") == 0)
259 {
260 if (hddType != HardDiskType_Immutable)
261 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));
262 }
263 else
264 {
265 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());
266 }
267 }
268 else
269 return errorArgument("Hard disk image not registered");
270 }
271 else if (strcmp(argv[1], "compact") == 0)
272 {
273#if 1
274 RTPrintf("Error: Shrink hard disk operation is temporarily unavailable!\n");
275 return 1;
276#else
277 /* the hard disk image might not be registered */
278 if (!hardDisk)
279 {
280 virtualBox->OpenHardDisk2(Bstr(argv[0]), hardDisk.asOutParam());
281 if (!hardDisk)
282 return errorArgument("Hard disk image not found");
283 }
284
285 Bstr format;
286 hardDisk->COMGETTER(Format)(format.asOutParam());
287 if (format != "VDI")
288 return errorArgument("Invalid hard disk type. The command only works on VDI files\n");
289
290 Bstr fileName;
291 hardDisk->COMGETTER(Location)(fileName.asOutParam());
292
293 /* make sure the object reference is released */
294 hardDisk = NULL;
295
296 unsigned uProcent;
297
298 RTPrintf("Shrinking '%lS': 0%%", fileName.raw());
299 int vrc = VDIShrinkImage(Utf8Str(fileName).raw(), hardDiskProgressCallback, &uProcent);
300 if (RT_FAILURE(vrc))
301 {
302 RTPrintf("Error while shrinking hard disk image: %Rrc\n", vrc);
303 rc = E_FAIL;
304 }
305#endif
306 }
307 else
308 return errorSyntax(USAGE_MODIFYHD, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
309
310 return SUCCEEDED(rc) ? 0 : 1;
311}
312
313int handleCloneHardDisk(int argc, char *argv[],
314 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
315{
316 Bstr src, dst;
317 Bstr format;
318 bool remember = false;
319
320 HRESULT rc;
321
322 /* Parse the arguments. */
323 for (int i = 0; i < argc; i++)
324 {
325 if (strcmp(argv[i], "-format") == 0)
326 {
327 if (argc <= i + 1)
328 {
329 return errorArgument("Missing argument to '%s'", argv[i]);
330 }
331 i++;
332 format = argv[i];
333 }
334 else if (strcmp(argv[i], "-remember") == 0 ||
335 strcmp(argv[i], "-register") == 0 /* backward compatiblity */)
336 {
337 remember = true;
338 }
339 else if (src.isEmpty())
340 {
341 src = argv[i];
342 }
343 else if (dst.isEmpty())
344 {
345 dst = argv[i];
346 }
347 else
348 {
349 return errorSyntax(USAGE_CLONEHD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
350 }
351 }
352
353 if (src.isEmpty())
354 return errorSyntax(USAGE_CLONEHD, "Mandatory UUID or input file parameter missing");
355 if (dst.isEmpty())
356 return errorSyntax(USAGE_CLONEHD, "Mandatory output file parameter missing");
357
358 ComPtr<IHardDisk2> srcDisk;
359 ComPtr<IHardDisk2> dstDisk;
360 bool unknown = false;
361
362 /* first guess is that it's a UUID */
363 Guid uuid(Utf8Str(src).raw());
364 rc = virtualBox->GetHardDisk2(uuid, srcDisk.asOutParam());
365 /* no? then it must be a filename */
366 if (FAILED (rc))
367 {
368 rc = virtualBox->FindHardDisk2(src, srcDisk.asOutParam());
369 /* no? well, then it's an unkwnown image */
370 if (FAILED (rc))
371 {
372 CHECK_ERROR(virtualBox, OpenHardDisk2(src, srcDisk.asOutParam()));
373 if (SUCCEEDED (rc))
374 {
375 unknown = true;
376 }
377 }
378 }
379
380 do
381 {
382 if (!SUCCEEDED(rc))
383 break;
384
385 if (format.isEmpty())
386 {
387 /* get the format of the source hard disk */
388 CHECK_ERROR_BREAK(srcDisk, COMGETTER(Format) (format.asOutParam()));
389 }
390
391 CHECK_ERROR_BREAK(virtualBox, CreateHardDisk2(format, dst, dstDisk.asOutParam()));
392
393 ComPtr<IProgress> progress;
394 CHECK_ERROR_BREAK(srcDisk, CloneTo(dstDisk, progress.asOutParam()));
395
396 showProgress(progress);
397 progress->COMGETTER(ResultCode)(&rc);
398 if (FAILED(rc))
399 {
400 com::ProgressErrorInfo info(progress);
401 if (info.isBasicAvailable())
402 RTPrintf("Error: failed to clone hard disk. Error message: %lS\n", info.getText().raw());
403 else
404 RTPrintf("Error: failed to clone hard disk. No error message available!\n");
405 break;
406 }
407
408 CHECK_ERROR_BREAK(dstDisk, COMGETTER(Id)(uuid.asOutParam()));
409
410 RTPrintf("Clone hard disk created in format '%ls'. UUID: %s\n",
411 format.raw(), uuid.toString().raw());
412 }
413 while (0);
414
415 if (!remember && !dstDisk.isNull())
416 {
417 /* forget the created clone */
418 dstDisk->Close();
419 }
420
421 if (unknown)
422 {
423 /* close the unknown hard disk to forget it again */
424 srcDisk->Close();
425 }
426
427 return SUCCEEDED(rc) ? 0 : 1;
428}
429
430int handleConvertFromRaw(int argc, char *argv[])
431{
432 VDIMAGETYPE enmImgType = VD_IMAGE_TYPE_NORMAL;
433 bool fReadFromStdIn = false;
434 const char *format = "VDI";
435 const char *srcfilename = NULL;
436 const char *dstfilename = NULL;
437 const char *filesize = NULL;
438 unsigned uImageFlags = 0; /**< @todo allow creation of non-default image variants */
439 void *pvBuf = NULL;
440
441 for (int i = 0; i < argc; i++)
442 {
443 if (!strcmp(argv[i], "-static"))
444 {
445 enmImgType = VD_IMAGE_TYPE_FIXED;
446 }
447 else if (strcmp(argv[i], "-format") == 0)
448 {
449 if (argc <= i + 1)
450 {
451 return errorArgument("Missing argument to '%s'", argv[i]);
452 }
453 i++;
454 format = argv[i];
455 }
456 else
457 {
458 if (srcfilename)
459 {
460 if (dstfilename)
461 {
462 if (fReadFromStdIn && !filesize)
463 filesize = argv[i];
464 else
465 return errorSyntax(USAGE_CONVERTFROMRAW, "Incorrect number of parameters");
466 }
467 else
468 dstfilename = argv[i];
469 }
470 else
471 {
472 srcfilename = argv[i];
473#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
474 fReadFromStdIn = !strcmp(srcfilename, "stdin");
475#endif
476 }
477 }
478 }
479
480 if (!srcfilename || !dstfilename || (fReadFromStdIn && !filesize))
481 return errorSyntax(USAGE_CONVERTFROMRAW, "Incorrect number of parameters");
482 RTPrintf("Converting from raw image file=\"%s\" to file=\"%s\"...\n",
483 srcfilename, dstfilename);
484
485 int rc = VINF_SUCCESS;
486 PVBOXHDD pDisk = NULL;
487
488 PVDINTERFACE pVDIfs = NULL;
489 VDINTERFACE vdInterfaceError;
490 VDINTERFACEERROR vdInterfaceErrorCallbacks;
491 vdInterfaceErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);
492 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
493 vdInterfaceErrorCallbacks.pfnError = handleVDError;
494
495 rc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
496 &vdInterfaceErrorCallbacks, NULL, &pVDIfs);
497 AssertRC(rc);
498
499 /* open raw image file. */
500 RTFILE File;
501 if (fReadFromStdIn)
502 File = 0;
503 else
504 rc = RTFileOpen(&File, srcfilename, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
505 if (RT_FAILURE(rc))
506 {
507 RTPrintf("File=\"%s\" open error: %Rrf\n", srcfilename, rc);
508 goto out;
509 }
510
511 uint64_t cbFile;
512 /* get image size. */
513 if (fReadFromStdIn)
514 cbFile = RTStrToUInt64(filesize);
515 else
516 rc = RTFileGetSize(File, &cbFile);
517 if (RT_FAILURE(rc))
518 {
519 RTPrintf("Error getting image size for file \"%s\": %Rrc\n", srcfilename, rc);
520 goto out;
521 }
522
523 RTPrintf("Creating %s image with size %RU64 bytes (%RU64MB)...\n", (enmImgType == VD_IMAGE_TYPE_FIXED) ? "fixed" : "dynamic", cbFile, (cbFile + _1M - 1) / _1M);
524 char pszComment[256];
525 RTStrPrintf(pszComment, sizeof(pszComment), "Converted image from %s", srcfilename);
526 rc = VDCreate(pVDIfs, &pDisk);
527 if (RT_FAILURE(rc))
528 {
529 RTPrintf("Error while creating the virtual disk container: %Rrc\n", rc);
530 goto out;
531 }
532
533 Assert(RT_MIN(cbFile / 512 / 16 / 63, 16383) -
534 (unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383) == 0);
535 PDMMEDIAGEOMETRY PCHS, LCHS;
536 PCHS.cCylinders = (unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383);
537 PCHS.cHeads = 16;
538 PCHS.cSectors = 63;
539 LCHS.cCylinders = 0;
540 LCHS.cHeads = 0;
541 LCHS.cSectors = 0;
542 rc = VDCreateBase(pDisk, format, dstfilename, enmImgType, cbFile,
543 uImageFlags, pszComment, &PCHS, &LCHS, NULL,
544 VD_OPEN_FLAGS_NORMAL, NULL, NULL);
545 if (RT_FAILURE(rc))
546 {
547 RTPrintf("Error while creating the disk image \"%s\": %Rrc\n", dstfilename, rc);
548 goto out;
549 }
550
551 size_t cbBuffer;
552 cbBuffer = _1M;
553 pvBuf = RTMemAlloc(cbBuffer);
554 if (!pvBuf)
555 {
556 rc = VERR_NO_MEMORY;
557 RTPrintf("Not enough memory allocating buffers for image \"%s\": %Rrc\n", dstfilename, rc);
558 goto out;
559 }
560
561 uint64_t offFile;
562 offFile = 0;
563 while (offFile < cbFile)
564 {
565 size_t cbRead;
566 size_t cbToRead;
567 cbRead = 0;
568 cbToRead = cbFile - offFile >= (uint64_t)cbBuffer ?
569 cbBuffer : (size_t) (cbFile - offFile);
570 rc = RTFileRead(File, pvBuf, cbToRead, &cbRead);
571 if (RT_FAILURE(rc) || !cbRead)
572 break;
573 rc = VDWrite(pDisk, offFile, pvBuf, cbRead);
574 if (RT_FAILURE(rc))
575 {
576 RTPrintf("Failed to write to disk image \"%s\": %Rrc\n", dstfilename, rc);
577 goto out;
578 }
579 offFile += cbRead;
580 }
581
582out:
583 if (pvBuf)
584 RTMemFree(pvBuf);
585 if (pDisk)
586 VDClose(pDisk, RT_FAILURE(rc));
587 if (File != NIL_RTFILE)
588 RTFileClose(File);
589
590 return RT_FAILURE(rc);
591}
592
593int handleAddiSCSIDisk(int argc, char *argv[],
594 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
595{
596 HRESULT rc;
597 Bstr server;
598 Bstr target;
599 Bstr port;
600 Bstr lun;
601 Bstr username;
602 Bstr password;
603 Bstr comment;
604 bool fIntNet = false;
605
606 /* at least server and target */
607 if (argc < 4)
608 return errorSyntax(USAGE_ADDISCSIDISK, "Not enough parameters");
609
610 /* let's have a closer look at the arguments */
611 for (int i = 0; i < argc; i++)
612 {
613 if (strcmp(argv[i], "-server") == 0)
614 {
615 if (argc <= i + 1)
616 return errorArgument("Missing argument to '%s'", argv[i]);
617 i++;
618 server = argv[i];
619 }
620 else if (strcmp(argv[i], "-target") == 0)
621 {
622 if (argc <= i + 1)
623 return errorArgument("Missing argument to '%s'", argv[i]);
624 i++;
625 target = argv[i];
626 }
627 else if (strcmp(argv[i], "-port") == 0)
628 {
629 if (argc <= i + 1)
630 return errorArgument("Missing argument to '%s'", argv[i]);
631 i++;
632 port = argv[i];
633 }
634 else if (strcmp(argv[i], "-lun") == 0)
635 {
636 if (argc <= i + 1)
637 return errorArgument("Missing argument to '%s'", argv[i]);
638 i++;
639 lun = argv[i];
640 }
641 else if (strcmp(argv[i], "-encodedlun") == 0)
642 {
643 if (argc <= i + 1)
644 return errorArgument("Missing argument to '%s'", argv[i]);
645 i++;
646 lun = BstrFmt("enc%s", argv[i]);
647 }
648 else if (strcmp(argv[i], "-username") == 0)
649 {
650 if (argc <= i + 1)
651 return errorArgument("Missing argument to '%s'", argv[i]);
652 i++;
653 username = argv[i];
654 }
655 else if (strcmp(argv[i], "-password") == 0)
656 {
657 if (argc <= i + 1)
658 return errorArgument("Missing argument to '%s'", argv[i]);
659 i++;
660 password = argv[i];
661 }
662 else if (strcmp(argv[i], "-comment") == 0)
663 {
664 if (argc <= i + 1)
665 return errorArgument("Missing argument to '%s'", argv[i]);
666 i++;
667 comment = argv[i];
668 }
669 else if (strcmp(argv[i], "-intnet") == 0)
670 {
671 i++;
672 fIntNet = true;
673 }
674 else
675 return errorSyntax(USAGE_ADDISCSIDISK, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
676 }
677
678 /* check for required options */
679 if (!server || !target)
680 return errorSyntax(USAGE_ADDISCSIDISK, "Parameters -server and -target are required");
681
682 do
683 {
684 ComPtr<IHardDisk2> hardDisk;
685 CHECK_ERROR_BREAK (aVirtualBox,
686 CreateHardDisk2(Bstr ("iSCSI"),
687 BstrFmt ("%ls/%ls", server.raw(), target.raw()),
688 hardDisk.asOutParam()));
689 CheckComRCBreakRC (rc);
690
691 if (!comment.isNull())
692 CHECK_ERROR_BREAK(hardDisk, COMSETTER(Description)(comment));
693
694 if (!port.isNull())
695 server = BstrFmt ("%ls:%ls", server.raw(), port.raw());
696
697 com::SafeArray <BSTR> names;
698 com::SafeArray <BSTR> values;
699
700 Bstr ("TargetAddress").detachTo (names.appendedRaw());
701 server.detachTo (values.appendedRaw());
702 Bstr ("TargetName").detachTo (names.appendedRaw());
703 target.detachTo (values.appendedRaw());
704
705 if (!lun.isNull())
706 {
707 Bstr ("LUN").detachTo (names.appendedRaw());
708 lun.detachTo (values.appendedRaw());
709 }
710 if (!username.isNull())
711 {
712 Bstr ("InitiatorUsername").detachTo (names.appendedRaw());
713 username.detachTo (values.appendedRaw());
714 }
715 if (!password.isNull())
716 {
717 Bstr ("InitiatorSecret").detachTo (names.appendedRaw());
718 password.detachTo (values.appendedRaw());
719 }
720
721 /// @todo add -initiator option
722 Bstr ("InitiatorName").detachTo (names.appendedRaw());
723 Bstr ("iqn.2008-04.com.sun.virtualbox.initiator").detachTo (values.appendedRaw());
724
725 /// @todo add -targetName and -targetPassword options
726
727 if (fIntNet)
728 {
729 Bstr ("HostIPStack").detachTo (names.appendedRaw());
730 Bstr ("0").detachTo (values.appendedRaw());
731 }
732
733 CHECK_ERROR_BREAK (hardDisk,
734 SetProperties (ComSafeArrayAsInParam (names),
735 ComSafeArrayAsInParam (values)));
736
737 Guid guid;
738 CHECK_ERROR(hardDisk, COMGETTER(Id)(guid.asOutParam()));
739 RTPrintf("iSCSI disk created. UUID: %s\n", guid.toString().raw());
740 }
741 while (0);
742
743 return SUCCEEDED(rc) ? 0 : 1;
744}
745
746
747int handleShowHardDiskInfo(int argc, char *argv[],
748 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
749{
750 HRESULT rc;
751
752 if (argc != 1)
753 return errorSyntax(USAGE_SHOWHDINFO, "Incorrect number of parameters");
754
755 ComPtr<IHardDisk2> hardDisk;
756 Bstr filepath;
757
758 bool unknown = false;
759
760 /* first guess is that it's a UUID */
761 Guid uuid(argv[0]);
762 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
763 /* no? then it must be a filename */
764 if (FAILED (rc))
765 {
766 filepath = argv[0];
767 rc = virtualBox->FindHardDisk2(filepath, hardDisk.asOutParam());
768 /* no? well, then it's an unkwnown image */
769 if (FAILED (rc))
770 {
771 CHECK_ERROR(virtualBox, OpenHardDisk2(filepath, hardDisk.asOutParam()));
772 if (SUCCEEDED (rc))
773 {
774 unknown = true;
775 }
776 }
777 }
778 do
779 {
780 if (!SUCCEEDED(rc))
781 break;
782
783 hardDisk->COMGETTER(Id)(uuid.asOutParam());
784 RTPrintf("UUID: %s\n", uuid.toString().raw());
785
786 /* check for accessibility */
787 /// @todo NEWMEDIA check accessibility of all parents
788 /// @todo NEWMEDIA print the full state value
789 MediaState_T state;
790 CHECK_ERROR_BREAK (hardDisk, COMGETTER(State)(&state));
791 RTPrintf("Accessible: %s\n", state != MediaState_Inaccessible ? "yes" : "no");
792
793 if (state == MediaState_Inaccessible)
794 {
795 Bstr err;
796 CHECK_ERROR_BREAK (hardDisk, COMGETTER(LastAccessError)(err.asOutParam()));
797 RTPrintf("Access Error: %lS\n", err.raw());
798 }
799
800 Bstr description;
801 hardDisk->COMGETTER(Description)(description.asOutParam());
802 if (description)
803 {
804 RTPrintf("Description: %lS\n", description.raw());
805 }
806
807 ULONG64 logicalSize;
808 hardDisk->COMGETTER(LogicalSize)(&logicalSize);
809 RTPrintf("Logical size: %llu MBytes\n", logicalSize);
810 ULONG64 actualSize;
811 hardDisk->COMGETTER(Size)(&actualSize);
812 RTPrintf("Current size on disk: %llu MBytes\n", actualSize >> 20);
813
814 HardDiskType_T type;
815 hardDisk->COMGETTER(Type)(&type);
816 const char *typeStr = "unknown";
817 switch (type)
818 {
819 case HardDiskType_Normal:
820 typeStr = "normal";
821 break;
822 case HardDiskType_Immutable:
823 typeStr = "immutable";
824 break;
825 case HardDiskType_Writethrough:
826 typeStr = "writethrough";
827 break;
828 }
829 RTPrintf("Type: %s\n", typeStr);
830
831 Bstr format;
832 hardDisk->COMGETTER(Format)(format.asOutParam());
833 RTPrintf("Storage format: %lS\n", format.raw());
834
835 if (!unknown)
836 {
837 com::SafeGUIDArray machineIds;
838 hardDisk->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(machineIds));
839 for (size_t j = 0; j < machineIds.size(); ++ j)
840 {
841 ComPtr<IMachine> machine;
842 CHECK_ERROR(virtualBox, GetMachine(machineIds[j], machine.asOutParam()));
843 ASSERT(machine);
844 Bstr name;
845 machine->COMGETTER(Name)(name.asOutParam());
846 machine->COMGETTER(Id)(uuid.asOutParam());
847 RTPrintf("%s%lS (UUID: %RTuuid)\n",
848 j == 0 ? "In use by VMs: " : " ",
849 name.raw(), &machineIds[j]);
850 }
851 /// @todo NEWMEDIA check usage in snapshots too
852 /// @todo NEWMEDIA also list children and say 'differencing' for
853 /// hard disks with the parent or 'base' otherwise.
854 }
855
856 Bstr loc;
857 hardDisk->COMGETTER(Location)(loc.asOutParam());
858 RTPrintf("Location: %lS\n", loc.raw());
859 }
860 while (0);
861
862 if (unknown)
863 {
864 /* close the unknown hard disk to forget it again */
865 hardDisk->Close();
866 }
867
868 return SUCCEEDED(rc) ? 0 : 1;
869}
870
871int handleOpenMedium(int argc, char *argv[],
872 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
873{
874 HRESULT rc;
875
876 if (argc < 2)
877 return errorSyntax(USAGE_REGISTERIMAGE, "Not enough parameters");
878
879 Bstr filepath(argv[1]);
880
881 if (strcmp(argv[0], "disk") == 0)
882 {
883 const char *type = NULL;
884 /* there can be a type parameter */
885 if ((argc > 2) && (argc != 4))
886 return errorSyntax(USAGE_REGISTERIMAGE, "Incorrect number of parameters");
887 if (argc == 4)
888 {
889 if (strcmp(argv[2], "-type") != 0)
890 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());
891 if ( (strcmp(argv[3], "normal") != 0)
892 && (strcmp(argv[3], "immutable") != 0)
893 && (strcmp(argv[3], "writethrough") != 0))
894 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(argv[3]).raw());
895 type = argv[3];
896 }
897
898 ComPtr<IHardDisk2> hardDisk;
899 CHECK_ERROR(virtualBox, OpenHardDisk2(filepath, hardDisk.asOutParam()));
900 if (SUCCEEDED(rc) && hardDisk)
901 {
902 /* change the type if requested */
903 if (type)
904 {
905 if (strcmp(type, "normal") == 0)
906 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));
907 else if (strcmp(type, "immutable") == 0)
908 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));
909 else if (strcmp(type, "writethrough") == 0)
910 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
911 }
912 }
913 }
914 else if (strcmp(argv[0], "dvd") == 0)
915 {
916 ComPtr<IDVDImage2> dvdImage;
917 CHECK_ERROR(virtualBox, OpenDVDImage(filepath, Guid(), dvdImage.asOutParam()));
918 }
919 else if (strcmp(argv[0], "floppy") == 0)
920 {
921 ComPtr<IFloppyImage2> floppyImage;
922 CHECK_ERROR(virtualBox, OpenFloppyImage(filepath, Guid(), floppyImage.asOutParam()));
923 }
924 else
925 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
926
927 return SUCCEEDED(rc) ? 0 : 1;
928}
929
930int handleCloseMedium(int argc, char *argv[],
931 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
932{
933 HRESULT rc;
934
935 if (argc != 2)
936 return errorSyntax(USAGE_UNREGISTERIMAGE, "Incorrect number of parameters");
937
938 /* first guess is that it's a UUID */
939 Guid uuid(argv[1]);
940
941 if (strcmp(argv[0], "disk") == 0)
942 {
943 ComPtr<IHardDisk2> hardDisk;
944 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
945 /* not a UUID or not registered? Then it must be a filename */
946 if (!hardDisk)
947 {
948 CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(argv[1]), hardDisk.asOutParam()));
949 }
950 if (SUCCEEDED(rc) && hardDisk)
951 {
952 CHECK_ERROR(hardDisk, Close());
953 }
954 }
955 else
956 if (strcmp(argv[0], "dvd") == 0)
957 {
958 ComPtr<IDVDImage2> dvdImage;
959 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
960 /* not a UUID or not registered? Then it must be a filename */
961 if (!dvdImage)
962 {
963 CHECK_ERROR(virtualBox, FindDVDImage(Bstr(argv[1]), dvdImage.asOutParam()));
964 }
965 if (SUCCEEDED(rc) && dvdImage)
966 {
967 CHECK_ERROR(dvdImage, Close());
968 }
969 }
970 else
971 if (strcmp(argv[0], "floppy") == 0)
972 {
973 ComPtr<IFloppyImage2> floppyImage;
974 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
975 /* not a UUID or not registered? Then it must be a filename */
976 if (!floppyImage)
977 {
978 CHECK_ERROR(virtualBox, FindFloppyImage(Bstr(argv[1]), floppyImage.asOutParam()));
979 }
980 if (SUCCEEDED(rc) && floppyImage)
981 {
982 CHECK_ERROR(floppyImage, Close());
983 }
984 }
985 else
986 return errorSyntax(USAGE_UNREGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
987
988 return SUCCEEDED(rc) ? 0 : 1;
989}
990#endif /* !VBOX_ONLY_DOCS */
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