24
24
#include <errno.h>
25
25
#include "virtualbox.h"
26
26
27
+ // From virtualbox/include/VBox/HostServices/GuestPropertySvc.h
28
+ #define GUEST_PROP_FN_GET_PROP 1
29
+ #define GUEST_PROP_FN_DEL_PROP 4
30
+
27
31
static void _cleanup_close (int * fd ) {
28
32
if (* fd != -1 ) {
29
33
close (* fd );
@@ -86,13 +90,16 @@ static int connect(int fd, uint32_t *client_id) {
86
90
}
87
91
88
92
static int get_prop (int fd , uint32_t client_id , const char * name , void * * value , size_t * size ) {
93
+ // xref VbglR3GuestPropRead() in
94
+ // virtualbox/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestProp.cpp
95
+
89
96
// init header
90
97
size_t msg_size = sizeof (struct vbg_ioctl_hgcm_call ) + 4 * sizeof (struct vmmdev_hgcm_function_parameter64 );
91
98
struct vbg_ioctl_hgcm_call _cleanup_free_ * msg = calloc (1 , msg_size );
92
99
// init_header re-adds the size of msg->hdr
93
100
init_header (& msg -> hdr , msg_size - sizeof (msg -> hdr ), msg_size - sizeof (msg -> hdr ));
94
101
msg -> client_id = client_id ;
95
- msg -> function = 1 ; // GUEST_PROP_FN_GET_PROP
102
+ msg -> function = GUEST_PROP_FN_GET_PROP ;
96
103
msg -> timeout_ms = -1 ; // inf
97
104
msg -> interruptible = 1 ;
98
105
msg -> parm_count = 4 ;
@@ -147,6 +154,38 @@ static int get_prop(int fd, uint32_t client_id, const char *name, void **value,
147
154
}
148
155
}
149
156
157
+ static int del_prop (int fd , uint32_t client_id , const char * name ) {
158
+ // xref VbglR3GuestPropDelete() in
159
+ // virtualbox/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestProp.cpp
160
+
161
+ // init header
162
+ size_t msg_size = sizeof (struct vbg_ioctl_hgcm_call ) + sizeof (struct vmmdev_hgcm_function_parameter64 );
163
+ struct vbg_ioctl_hgcm_call _cleanup_free_ * msg = calloc (1 , msg_size );
164
+ // init_header re-adds the size of msg->hdr
165
+ init_header (& msg -> hdr , msg_size - sizeof (msg -> hdr ), msg_size - sizeof (msg -> hdr ));
166
+ msg -> client_id = client_id ;
167
+ msg -> function = GUEST_PROP_FN_DEL_PROP ;
168
+ msg -> timeout_ms = -1 ; // inf
169
+ msg -> interruptible = 1 ;
170
+ msg -> parm_count = 1 ;
171
+
172
+ // init arguments
173
+ struct vmmdev_hgcm_function_parameter64 * params = (void * ) (msg + 1 );
174
+ // property name (in)
175
+ params [0 ].type = VMMDEV_HGCM_PARM_TYPE_LINADDR_IN ;
176
+ params [0 ].u .pointer .size = strlen (name ) + 1 ;
177
+ params [0 ].u .pointer .u .linear_addr = (uintptr_t ) name ;
178
+
179
+ // delete value
180
+ if (ioctl (fd , VBG_IOCTL_HGCM_CALL_64 (msg_size ), msg )) {
181
+ return VERR_GENERAL_FAILURE ;
182
+ }
183
+ if (msg -> hdr .rc != VINF_SUCCESS ) {
184
+ return msg -> hdr .rc ;
185
+ }
186
+ return VINF_SUCCESS ;
187
+ }
188
+
150
189
static int disconnect (int fd , uint32_t client_id ) {
151
190
struct vbg_ioctl_hgcm_disconnect msg = {
152
191
.u = {
@@ -162,7 +201,7 @@ static int disconnect(int fd, uint32_t client_id) {
162
201
return msg .hdr .rc ;
163
202
}
164
203
165
- int virtualbox_get_guest_property ( char * name , void * * value , size_t * size ) {
204
+ static int start_connection ( uint32_t * client_id ) {
166
205
// clear any previous garbage in errno for error returns
167
206
errno = 0 ;
168
207
@@ -179,12 +218,26 @@ int virtualbox_get_guest_property(char *name, void **value, size_t *size) {
179
218
}
180
219
181
220
// connect to property service
182
- uint32_t client_id ;
183
- ret = connect (fd , & client_id );
221
+ ret = connect (fd , client_id );
184
222
if (ret != VINF_SUCCESS ) {
185
223
return ret ;
186
224
}
187
225
226
+ // return fd
227
+ ret = fd ;
228
+ fd = -1 ;
229
+ return ret ;
230
+ }
231
+
232
+ int virtualbox_get_guest_property (char * name , void * * value , size_t * size ) {
233
+ // connect
234
+ uint32_t client_id ;
235
+ int ret = start_connection (& client_id );
236
+ if (ret < 0 ) {
237
+ return ret ;
238
+ }
239
+ int _cleanup_close_ fd = ret ;
240
+
188
241
// get property
189
242
ret = get_prop (fd , client_id , name , value , size );
190
243
if (ret != VINF_SUCCESS ) {
@@ -206,3 +259,32 @@ int virtualbox_get_guest_property(char *name, void **value, size_t *size) {
206
259
errno = 0 ;
207
260
return 0 ;
208
261
}
262
+
263
+ int virtualbox_delete_guest_property (char * name ) {
264
+ // connect
265
+ uint32_t client_id ;
266
+ int ret = start_connection (& client_id );
267
+ if (ret < 0 ) {
268
+ return ret ;
269
+ }
270
+ int _cleanup_close_ fd = ret ;
271
+
272
+ // delete property
273
+ ret = del_prop (fd , client_id , name );
274
+ if (ret != VINF_SUCCESS ) {
275
+ disconnect (fd , client_id );
276
+ return ret ;
277
+ }
278
+
279
+ // disconnect
280
+ ret = disconnect (fd , client_id );
281
+ if (ret != VINF_SUCCESS ) {
282
+ // we could ignore the failure, but better to make sure bugs
283
+ // are noticed
284
+ return ret ;
285
+ }
286
+
287
+ // for clarity, ensure the Go error return is nil
288
+ errno = 0 ;
289
+ return 0 ;
290
+ }
0 commit comments