1
/* $Id: tstVDSetUuid.cpp $ */
3
* Simple VBox HDD container test utility for changing the uuid of images.
7
* Copyright (C) 2010 Oracle Corporation
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.
18
/*******************************************************************************
20
*******************************************************************************/
21
#include <VBox/VBoxHDD.h>
23
#include <iprt/initterm.h>
24
#include <iprt/buildconfig.h>
25
#include <iprt/path.h>
26
#include <iprt/string.h>
27
#include <iprt/uuid.h>
28
#include <iprt/stream.h>
29
#include <iprt/message.h>
30
#include <iprt/getopt.h>
32
const char *g_pszProgName = "";
34
static const RTGETOPTDEF s_aOptions[] =
36
{ "--filename", 'f', RTGETOPT_REQ_STRING },
37
{ "--format", 'o', RTGETOPT_REQ_STRING },
38
{ "--uuid", 'u', RTGETOPT_REQ_UUID },
39
{ "--parentuuid", 'p', RTGETOPT_REQ_UUID },
40
{ "--zeroparentuuid", 'P', RTGETOPT_REQ_NOTHING }
43
static void showUsage(void)
45
RTStrmPrintf(g_pStdErr,
47
" --filename <filename>\n"
48
" [--format VDI|VMDK|VHD|...]\n"
50
" [--parentuuid <uuid>]\n"
51
" [--zeroparentuuid]\n",
55
static DECLCALLBACK(void) handleVDError(void *pvUser, int rc, RT_SRC_POS_DECL,
56
const char *pszFormat, va_list va)
60
RTMsgErrorV(pszFormat, va);
63
static int handleVDMessage(void *pvUser, const char *pszFormat, ...)
67
va_start(args, pszFormat);
68
RTMsgWarningV(pszFormat, args);
73
int main(int argc, char *argv[])
77
const char *pszFilename = NULL;
78
char *pszFormat = NULL;
81
bool fSetImageUuid = false;
82
bool fSetParentUuid = false;
84
g_pszProgName = RTPathFilename(argv[0]);
86
RTUuidClear(&imageUuid);
87
RTUuidClear(&parentUuid);
89
/* Parse the command line. */
91
RTGETOPTUNION ValueUnion;
92
RTGETOPTSTATE GetState;
93
RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /* fFlags */);
94
while ((ch = RTGetOpt(&GetState, &ValueUnion)))
98
case 'f': // --filename
99
pszFilename = ValueUnion.psz;
101
case 'o': // --format
102
pszFormat = RTStrDup(ValueUnion.psz);
105
imageUuid = ValueUnion.Uuid;
106
fSetImageUuid = true;
108
case 'p': // --parentuuid
109
parentUuid = ValueUnion.Uuid;
110
fSetParentUuid = true;
112
case 'P': // --zeroparentuuid
113
RTUuidClear(&parentUuid);
114
fSetParentUuid = true;
119
case 'V': // --version
120
RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
123
ch = RTGetOptPrintError(ch, &ValueUnion);
129
/* Check for mandatory parameters. */
132
RTMsgError("Mandatory --filename option missing\n");
137
/* Check for consistency of optional parameters. */
138
if (fSetImageUuid && RTUuidIsNull(&imageUuid))
140
RTMsgError("Invalid parameter to --uuid option\n");
145
PVDINTERFACE pVDIfs = NULL;
146
VDINTERFACE vdInterfaceError;
147
VDINTERFACEERROR vdInterfaceErrorCallbacks;
148
vdInterfaceErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);
149
vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
150
vdInterfaceErrorCallbacks.pfnError = handleVDError;
151
vdInterfaceErrorCallbacks.pfnMessage = handleVDMessage;
153
rc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
154
&vdInterfaceErrorCallbacks, NULL, &pVDIfs);
156
/* Autodetect image format. */
159
/* Don't pass error interface, as that would triggers error messages
160
* because some backends fail to open the image. */
161
rc = VDGetFormat(NULL, pszFilename, &pszFormat);
164
RTMsgError("Format autodetect failed: %Rrc\n", rc);
170
rc = VDCreate(pVDIfs, &pVD);
173
RTMsgError("Cannot create the virtual disk container: %Rrc\n", rc);
177
rc = VDOpen(pVD, pszFormat, pszFilename, VD_OPEN_FLAGS_NORMAL, NULL);
180
RTMsgError("Cannot open the virtual disk image \"%s\": %Rrc\n",
186
rc = VDGetUuid(pVD, VD_LAST_IMAGE, &oldImageUuid);
189
RTMsgError("Cannot get UUID of virtual disk image \"%s\": %Rrc\n",
193
RTPrintf("Old image UUID: %RTuuid\n", &oldImageUuid);
195
RTUUID oldParentUuid;
196
rc = VDGetParentUuid(pVD, VD_LAST_IMAGE, &oldParentUuid);
199
RTMsgError("Cannot get parent UUID of virtual disk image \"%s\": %Rrc\n",
203
RTPrintf("Old parent UUID: %RTuuid\n", &oldParentUuid);
207
RTPrintf("New image UUID: %RTuuid\n", &imageUuid);
208
rc = VDSetUuid(pVD, VD_LAST_IMAGE, &imageUuid);
211
RTMsgError("Cannot set UUID of virtual disk image \"%s\": %Rrc\n",
219
RTPrintf("New parent UUID: %RTuuid\n", &parentUuid);
220
rc = VDSetParentUuid(pVD, VD_LAST_IMAGE, &parentUuid);
223
RTMsgError("Cannot set parent UUID of virtual disk image \"%s\": %Rrc\n",
229
rc = VDCloseAll(pVD);
232
RTMsgError("Closing image failed! rc=%Rrc\n", rc);
238
RTStrFree(pszFormat);
245
RTMsgError("Unloading backends failed! rc=%Rrc\n", rc);