1 /****************************************************************************
2 **
3 ** Copyright (C) 2009-2010 Andrey Rijov <ANDron142@yandex.ru>
4 **
5 ** This file is part of AQEMU.
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License as published by
9 ** the Free Software Foundation; either version 2 of the License.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 ** Boston, MA 02110-1301, USA.
20 **
21 ****************************************************************************/
22
23 #include <QFile>
24 #include <QSettings>
25
26 #include "Utils.h"
27 #include "HDD_Image_Info.h"
28
HDD_Image_Info(QObject * parent)29 HDD_Image_Info::HDD_Image_Info( QObject *parent )
30 : QObject( parent )
31 {
32 QEMU_IMG_Proc = new QProcess( this );
33 }
34
Get_Disk_Info() const35 VM::Disk_Info HDD_Image_Info::Get_Disk_Info() const
36 {
37 return Info;
38 }
39
Update_Disk_Info(const QString & path)40 void HDD_Image_Info::Update_Disk_Info( const QString &path )
41 {
42 Info.Image_File_Name = path;
43
44 if( Info.Image_File_Name.isEmpty() )
45 {
46 Clear_Info();
47 return;
48 }
49
50 if( QFile::exists(Info.Image_File_Name) == false )
51 {
52 AQWarning( "void QEMU_IMG_Thread::run()",
53 "Image \"" + Info.Image_File_Name + "\" does not exist!" );
54 Clear_Info();
55 return;
56 }
57 else
58 {
59 QStringList args;
60 args << "info" << Info.Image_File_Name;
61
62 QEMU_IMG_Proc = new QProcess( this );
63 QSettings settings;
64 QEMU_IMG_Proc->start( settings.value("QEMU-IMG_Path", "qemu-img").toString(), args );
65
66 connect( QEMU_IMG_Proc, SIGNAL(finished(int, QProcess::ExitStatus)),
67 this, SLOT(Parse_Info(int, QProcess::ExitStatus)), Qt::DirectConnection );
68
69 connect( QEMU_IMG_Proc, SIGNAL(error(QProcess::ProcessError)),
70 this, SLOT(Clear_Info()), Qt::DirectConnection );
71 }
72 }
73
Clear_Info()74 void HDD_Image_Info::Clear_Info()
75 {
76 AQDebug( "void HDD_Image_Info::Clear_Info()",
77 "HDD Info Not Read!" );
78
79 VM_HDD tmp_hdd;
80 Info.Disk_Format = "";
81 Info.Virtual_Size = tmp_hdd.String_to_Device_Size( "0 G" );
82 Info.Disk_Size = tmp_hdd.String_to_Device_Size( "0 G" );
83 Info.Cluster_Size = 0;
84
85 emit Completed( false );
86 }
87
Parse_Info(int exitCode,QProcess::ExitStatus exitStatus)88 void HDD_Image_Info::Parse_Info( int exitCode, QProcess::ExitStatus exitStatus )
89 {
90
91
92 QByteArray info_str_ba = QEMU_IMG_Proc->readAll();
93 QString info_str = QString( info_str_ba ); // Create QString
94 if( info_str.isEmpty() )
95 {
96 AQDebug( "void HDD_Image_Info::Parse_Info( int exitCode, QProcess::ExitStatus exitStatus )",
97 "Data is empty." );
98 return;
99 }
100
101 QRegExp RegInfo = QRegExp( ".*image:[\\s]+([^\n\r]+).*file format:[\\s]+([\\w\\d]+).*virtual size:[\\s]+([\\d]+[.]*[\\d]*[KMG]+).*disk size:[\\s]+([\\d]+[.]*[\\d]*[KMG]+).*cluster_size:[\\s]+([\\d]+).*" );
102
103 bool cluster = true;
104 if( ! RegInfo.exactMatch(info_str) )
105 {
106 AQWarning( "void QEMU_IMG_Thread::Parse_Info( int exitCode, QProcess::ExitStatus exitStatus )",
107 "QRegExp With Cluster Size Not Matched!" );
108
109 RegInfo = QRegExp( QString(".*image:[\\s]+([^\n\r]+).*")+
110 QString("file format:[\\s]+([\\w\\d]+).*")+
111 QString("virtual size:[\\s]+([\\d]+[.]*[\\d]*[KMG]+).*")+
112 QString("disk size:[\\s]+([\\d]+[.]*[\\d]*[KMG]*).*") );
113
114 if( ! RegInfo.exactMatch(info_str) )
115 {
116 AQError( "void QEMU_IMG_Thread::Parse_Info( int exitCode, QProcess::ExitStatus exitStatus )",
117 "QRegExp Without Cluster Size Not Matched! Image: " + Info.Image_File_Name + "\nData: " + info_str );
118 Clear_Info();
119 return;
120 }
121 else
122 {
123 cluster = false;
124 }
125 }
126
127 QStringList info_lines = RegInfo.capturedTexts();
128
129 if( cluster && info_lines.count() != 6 )
130 {
131 AQError( "void QEMU_IMG_Thread::Parse_Info( int exitCode, QProcess::ExitStatus exitStatus )",
132 "info_str.count() != 6" );
133 Clear_Info();
134 return;
135 }
136 else if( ! cluster && info_lines.count() != 5 )
137 {
138 AQError( "void QEMU_IMG_Thread::Parse_Info( int exitCode, QProcess::ExitStatus exitStatus )",
139 "info_str.count() != 5" );
140 Clear_Info();
141 return;
142 }
143
144 if( info_lines[1] != Info.Image_File_Name )
145 {
146 AQWarning( "void QEMU_IMG_Thread::Parse_Info( int exitCode, QProcess::ExitStatus exitStatus )",
147 QString("info_lines[1] != Image_File_Name\nDetails:\n[[%1]]\n[[%2]]").arg(info_lines[1]).arg(Info.Image_File_Name) );
148 }
149
150 Info.Disk_Format = info_lines[ 2 ];
151 VM_HDD tmp_hdd;
152 Info.Virtual_Size = tmp_hdd.String_to_Device_Size( info_lines[3] );
153 Info.Disk_Size = tmp_hdd.String_to_Device_Size( info_lines[4] );
154 if( cluster ) Info.Cluster_Size = info_lines[ 5 ].toInt();
155 else Info.Cluster_Size = 0;
156
157 emit Completed( true );
158 }
159