VirtualBox

source: vbox/trunk/src/VBox/Main/src-all/DisplayUtils.cpp@ 94967

Last change on this file since 94967 was 94778, checked in by vboxsync, 3 years ago

Main/{DisplayUtils,MachineImpl}: Prepare the various screenshot getters to handle encrypted SSM streams when accessing the saved state file, bugref:9955

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1/* $Id: DisplayUtils.cpp 94778 2022-05-02 10:51:48Z vboxsync $ */
2/** @file
3 * Implementation of IDisplay helpers, currently only used in VBoxSVC.
4 */
5
6/*
7 * Copyright (C) 2010-2022 Oracle Corporation
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
18#include <DisplayUtils.h>
19
20#include <iprt/log.h>
21#include <VBox/err.h>
22#include <VBox/vmm/ssm.h>
23#include <VBoxVideo.h>
24
25int readSavedDisplayScreenshot(SsmStream &ssmStream, const Utf8Str &strStateFilePath,
26 uint32_t u32Type, uint8_t **ppu8Data, uint32_t *pcbData,
27 uint32_t *pu32Width, uint32_t *pu32Height)
28{
29 LogFlowFunc(("u32Type = %d [%s]\n", u32Type, strStateFilePath.c_str()));
30
31 /** @todo cache read data */
32 if (strStateFilePath.isEmpty())
33 {
34 /* No saved state data. */
35 return VERR_NOT_SUPPORTED;
36 }
37
38 uint8_t *pu8Data = NULL;
39 uint32_t cbData = 0;
40 uint32_t u32Width = 0;
41 uint32_t u32Height = 0;
42
43 PSSMHANDLE pSSM;
44 int vrc = ssmStream.open(strStateFilePath.c_str(), false /*fWrite*/, &pSSM);
45 if (RT_SUCCESS(vrc))
46 {
47 uint32_t uVersion;
48 vrc = SSMR3Seek(pSSM, "DisplayScreenshot", 1100 /*iInstance*/, &uVersion);
49 if (RT_SUCCESS(vrc))
50 {
51 if (uVersion == sSSMDisplayScreenshotVer)
52 {
53 uint32_t cBlocks;
54 vrc = SSMR3GetU32(pSSM, &cBlocks);
55 AssertRCReturn(vrc, vrc);
56
57 for (uint32_t i = 0; i < cBlocks; i++)
58 {
59 uint32_t cbBlock;
60 vrc = SSMR3GetU32(pSSM, &cbBlock);
61 AssertRCBreak(vrc);
62
63 uint32_t typeOfBlock;
64 vrc = SSMR3GetU32(pSSM, &typeOfBlock);
65 AssertRCBreak(vrc);
66
67 LogFlowFunc(("[%d] type %d, size %d bytes\n", i, typeOfBlock, cbBlock));
68
69 if (typeOfBlock == u32Type)
70 {
71 if (cbBlock > 2 * sizeof(uint32_t))
72 {
73 cbData = (uint32_t)(cbBlock - 2 * sizeof(uint32_t));
74 pu8Data = (uint8_t *)RTMemAlloc(cbData);
75 if (pu8Data == NULL)
76 {
77 vrc = VERR_NO_MEMORY;
78 break;
79 }
80
81 vrc = SSMR3GetU32(pSSM, &u32Width);
82 AssertRCBreak(vrc);
83 vrc = SSMR3GetU32(pSSM, &u32Height);
84 AssertRCBreak(vrc);
85 vrc = SSMR3GetMem(pSSM, pu8Data, cbData);
86 AssertRCBreak(vrc);
87 }
88 else
89 {
90 /* No saved state data. */
91 vrc = VERR_NOT_SUPPORTED;
92 }
93
94 break;
95 }
96 else
97 {
98 /* displaySSMSaveScreenshot did not write any data, if
99 * cbBlock was == 2 * sizeof (uint32_t).
100 */
101 if (cbBlock > 2 * sizeof (uint32_t))
102 {
103 vrc = SSMR3Skip(pSSM, cbBlock);
104 AssertRCBreak(vrc);
105 }
106 }
107 }
108 }
109 else
110 {
111 vrc = VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
112 }
113 }
114
115 ssmStream.close();
116 }
117
118 if (RT_SUCCESS(vrc))
119 {
120 if (u32Type == 0 && cbData % 4 != 0)
121 {
122 /* Bitmap is 32bpp, so data is invalid. */
123 vrc = VERR_SSM_UNEXPECTED_DATA;
124 }
125 }
126
127 if (RT_SUCCESS(vrc))
128 {
129 *ppu8Data = pu8Data;
130 *pcbData = cbData;
131 *pu32Width = u32Width;
132 *pu32Height = u32Height;
133 LogFlowFunc(("cbData %d, u32Width %d, u32Height %d\n", cbData, u32Width, u32Height));
134 }
135
136 LogFlowFunc(("vrc %Rrc\n", vrc));
137 return vrc;
138}
139
140void freeSavedDisplayScreenshot(uint8_t *pu8Data)
141{
142 /** @todo not necessary when caching is implemented. */
143 RTMemFree(pu8Data);
144}
145
146int readSavedGuestScreenInfo(SsmStream &ssmStream, const Utf8Str &strStateFilePath,
147 uint32_t u32ScreenId, uint32_t *pu32OriginX, uint32_t *pu32OriginY,
148 uint32_t *pu32Width, uint32_t *pu32Height, uint16_t *pu16Flags)
149{
150 LogFlowFunc(("u32ScreenId = %d [%s]\n", u32ScreenId, strStateFilePath.c_str()));
151
152 /** @todo cache read data */
153 if (strStateFilePath.isEmpty())
154 {
155 /* No saved state data. */
156 return VERR_NOT_SUPPORTED;
157 }
158
159 PSSMHANDLE pSSM;
160 int vrc = ssmStream.open(strStateFilePath.c_str(), false /*fWrite*/, &pSSM);
161 if (RT_SUCCESS(vrc))
162 {
163 uint32_t uVersion;
164 vrc = SSMR3Seek(pSSM, "DisplayData", 0 /*iInstance*/, &uVersion);
165 if (RT_SUCCESS(vrc))
166 {
167 /* Starting from sSSMDisplayVer2 we have pu32Width and pu32Height.
168 * Starting from sSSMDisplayVer3 we have all the rest of parameters we need. */
169 if (uVersion >= sSSMDisplayVer2)
170 {
171 uint32_t cMonitors;
172 SSMR3GetU32(pSSM, &cMonitors);
173 if (u32ScreenId > cMonitors)
174 {
175 vrc = VERR_INVALID_PARAMETER;
176 }
177 else
178 {
179 if (uVersion == sSSMDisplayVer2)
180 {
181 /* Skip all previous monitors, each 5 uint32_t, and the first 3 uint32_t entries. */
182 SSMR3Skip(pSSM, u32ScreenId * 5 * sizeof(uint32_t) + 3 * sizeof(uint32_t));
183 SSMR3GetU32(pSSM, pu32Width);
184 SSMR3GetU32(pSSM, pu32Height);
185 *pu32OriginX = 0;
186 *pu32OriginY = 0;
187 *pu16Flags = VBVA_SCREEN_F_ACTIVE;
188 }
189 else
190 {
191 /* Skip all previous monitors, each 8 uint32_t, and the first 3 uint32_t entries. */
192 SSMR3Skip(pSSM, u32ScreenId * 8 * sizeof(uint32_t) + 3 * sizeof(uint32_t));
193 SSMR3GetU32(pSSM, pu32Width);
194 SSMR3GetU32(pSSM, pu32Height);
195 SSMR3GetU32(pSSM, pu32OriginX);
196 SSMR3GetU32(pSSM, pu32OriginY);
197 uint32_t u32Flags = 0;
198 SSMR3GetU32(pSSM, &u32Flags);
199 *pu16Flags = (uint16_t)u32Flags;
200 }
201 }
202 }
203 else
204 {
205 vrc = VERR_NOT_SUPPORTED;
206 }
207 }
208
209 ssmStream.close();
210 }
211
212 LogFlowFunc(("vrc %Rrc\n", vrc));
213 return vrc;
214}
215
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