VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp@ 27856

Last change on this file since 27856 was 26753, checked in by vboxsync, 15 years ago

Main: Bstr makeover (third attempt) -- make Bstr(NULL) and Bstr() behave the same; resulting cleanup; make some more internal methods use Utf8Str instead of Bstr; fix a lot of CheckComArgNotNull??() usage

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.2 KB
Line 
1/* $Id: VBoxManageUSB.cpp 26753 2010-02-24 16:24:33Z vboxsync $ */
2/** @file
3 * VBoxManage - VirtualBox's command-line interface.
4 */
5
6/*
7 * Copyright (C) 2006-2009 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#include <VBox/com/com.h>
23#include <VBox/com/string.h>
24#include <VBox/com/Guid.h>
25#include <VBox/com/array.h>
26#include <VBox/com/ErrorInfo.h>
27#include <VBox/com/errorprint.h>
28#include <VBox/com/EventQueue.h>
29
30#include <VBox/com/VirtualBox.h>
31
32#include "VBoxManage.h"
33
34#include <iprt/asm.h>
35
36/* missing XPCOM <-> COM wrappers */
37#ifndef STDMETHOD_
38# define STDMETHOD_(ret, meth) NS_IMETHOD_(ret) meth
39#endif
40#ifndef NS_GET_IID
41# define NS_GET_IID(I) IID_##I
42#endif
43#ifndef RT_OS_WINDOWS
44#define IUnknown nsISupports
45#endif
46
47using namespace com;
48
49/**
50 * Quick IUSBDevice implementation for detaching / attaching
51 * devices to the USB Controller.
52 */
53class MyUSBDevice : public IUSBDevice
54{
55public:
56 // public initializer/uninitializer for internal purposes only
57 MyUSBDevice(uint16_t a_u16VendorId, uint16_t a_u16ProductId, uint16_t a_bcdRevision, uint64_t a_u64SerialHash, const char *a_pszComment)
58 : m_usVendorId(a_u16VendorId), m_usProductId(a_u16ProductId),
59 m_bcdRevision(a_bcdRevision), m_u64SerialHash(a_u64SerialHash),
60 m_bstrComment(a_pszComment),
61 m_cRefs(0)
62 {
63 }
64
65 STDMETHOD_(ULONG, AddRef)(void)
66 {
67 return ASMAtomicIncU32(&m_cRefs);
68 }
69 STDMETHOD_(ULONG, Release)(void)
70 {
71 ULONG cRefs = ASMAtomicDecU32(&m_cRefs);
72 if (!cRefs)
73 delete this;
74 return cRefs;
75 }
76 STDMETHOD(QueryInterface)(const IID &iid, void **ppvObject)
77 {
78 Guid guid(iid);
79 if (guid == Guid(NS_GET_IID(IUnknown)))
80 *ppvObject = (IUnknown *)this;
81#ifdef RT_OS_WINDOWS
82 else if (guid == Guid(NS_GET_IID(IDispatch)))
83 *ppvObject = (IDispatch *)this;
84#endif
85 else if (guid == Guid(NS_GET_IID(IUSBDevice)))
86 *ppvObject = (IUSBDevice *)this;
87 else
88 return E_NOINTERFACE;
89 AddRef();
90 return S_OK;
91 }
92
93 STDMETHOD(COMGETTER(Id))(OUT_GUID a_pId) { return E_NOTIMPL; }
94 STDMETHOD(COMGETTER(VendorId))(USHORT *a_pusVendorId) { *a_pusVendorId = m_usVendorId; return S_OK; }
95 STDMETHOD(COMGETTER(ProductId))(USHORT *a_pusProductId) { *a_pusProductId = m_usProductId; return S_OK; }
96 STDMETHOD(COMGETTER(Revision))(USHORT *a_pusRevision) { *a_pusRevision = m_bcdRevision; return S_OK; }
97 STDMETHOD(COMGETTER(SerialHash))(ULONG64 *a_pullSerialHash) { *a_pullSerialHash = m_u64SerialHash; return S_OK; }
98 STDMETHOD(COMGETTER(Manufacturer))(BSTR *a_pManufacturer) { return E_NOTIMPL; }
99 STDMETHOD(COMGETTER(Product))(BSTR *a_pProduct) { return E_NOTIMPL; }
100 STDMETHOD(COMGETTER(SerialNumber))(BSTR *a_pSerialNumber) { return E_NOTIMPL; }
101 STDMETHOD(COMGETTER(Address))(BSTR *a_pAddress) { return E_NOTIMPL; }
102
103private:
104 /** The vendor id of this USB device. */
105 USHORT m_usVendorId;
106 /** The product id of this USB device. */
107 USHORT m_usProductId;
108 /** The product revision number of this USB device.
109 * (high byte = integer; low byte = decimal) */
110 USHORT m_bcdRevision;
111 /** The USB serial hash of the device. */
112 uint64_t m_u64SerialHash;
113 /** The user comment string. */
114 Bstr m_bstrComment;
115 /** Reference counter. */
116 uint32_t volatile m_cRefs;
117};
118
119
120// types
121///////////////////////////////////////////////////////////////////////////////
122
123template <typename T>
124class Nullable
125{
126public:
127
128 Nullable() : mIsNull (true) {}
129 Nullable (const T &aValue, bool aIsNull = false)
130 : mIsNull (aIsNull), mValue (aValue) {}
131
132 bool isNull() const { return mIsNull; };
133 void setNull (bool aIsNull = true) { mIsNull = aIsNull; }
134
135 operator const T&() const { return mValue; }
136
137 Nullable &operator= (const T &aValue)
138 {
139 mValue = aValue;
140 mIsNull = false;
141 return *this;
142 }
143
144private:
145
146 bool mIsNull;
147 T mValue;
148};
149
150/** helper structure to encapsulate USB filter manipulation commands */
151struct USBFilterCmd
152{
153 struct USBFilter
154 {
155 USBFilter ()
156 : mAction (USBDeviceFilterAction_Null)
157 {}
158
159 Bstr mName;
160 Nullable <bool> mActive;
161 Bstr mVendorId;
162 Bstr mProductId;
163 Bstr mRevision;
164 Bstr mManufacturer;
165 Bstr mProduct;
166 Bstr mRemote;
167 Bstr mSerialNumber;
168 Nullable <ULONG> mMaskedInterfaces;
169 USBDeviceFilterAction_T mAction;
170 };
171
172 enum Action { Invalid, Add, Modify, Remove };
173
174 USBFilterCmd() : mAction (Invalid), mIndex (0), mGlobal (false) {}
175
176 Action mAction;
177 uint32_t mIndex;
178 /** flag whether the command target is a global filter */
179 bool mGlobal;
180 /** machine this command is targeted at (null for global filters) */
181 ComPtr<IMachine> mMachine;
182 USBFilter mFilter;
183};
184
185int handleUSBFilter (HandlerArg *a)
186{
187 HRESULT rc = S_OK;
188 USBFilterCmd cmd;
189
190 /* at least: 0: command, 1: index, 2: --target, 3: <target value> */
191 if (a->argc < 4)
192 return errorSyntax(USAGE_USBFILTER, "Not enough parameters");
193
194 /* which command? */
195 cmd.mAction = USBFilterCmd::Invalid;
196 if (!strcmp(a->argv[0], "add")) cmd.mAction = USBFilterCmd::Add;
197 else if (!strcmp(a->argv[0], "modify")) cmd.mAction = USBFilterCmd::Modify;
198 else if (!strcmp(a->argv[0], "remove")) cmd.mAction = USBFilterCmd::Remove;
199
200 if (cmd.mAction == USBFilterCmd::Invalid)
201 return errorSyntax(USAGE_USBFILTER, "Invalid parameter '%s'", a->argv[0]);
202
203 /* which index? */
204 if (VINF_SUCCESS != RTStrToUInt32Full (a->argv[1], 10, &cmd.mIndex))
205 return errorSyntax(USAGE_USBFILTER, "Invalid index '%s'", a->argv[1]);
206
207 switch (cmd.mAction)
208 {
209 case USBFilterCmd::Add:
210 case USBFilterCmd::Modify:
211 {
212 /* at least: 0: command, 1: index, 2: --target, 3: <target value>, 4: --name, 5: <name value> */
213 if (a->argc < 6)
214 {
215 if (cmd.mAction == USBFilterCmd::Add)
216 return errorSyntax(USAGE_USBFILTER_ADD, "Not enough parameters");
217
218 return errorSyntax(USAGE_USBFILTER_MODIFY, "Not enough parameters");
219 }
220
221 // set Active to true by default
222 // (assuming that the user sets up all necessary attributes
223 // at once and wants the filter to be active immediately)
224 if (cmd.mAction == USBFilterCmd::Add)
225 cmd.mFilter.mActive = true;
226
227 for (int i = 2; i < a->argc; i++)
228 {
229 if ( !strcmp(a->argv[i], "--target")
230 || !strcmp(a->argv[i], "-target"))
231 {
232 if (a->argc <= i + 1 || !*a->argv[i+1])
233 return errorArgument("Missing argument to '%s'", a->argv[i]);
234 i++;
235 if (!strcmp(a->argv[i], "global"))
236 cmd.mGlobal = true;
237 else
238 {
239 /* assume it's a UUID of a machine */
240 rc = a->virtualBox->GetMachine(Bstr(a->argv[i]), cmd.mMachine.asOutParam());
241 if (FAILED(rc) || !cmd.mMachine)
242 {
243 /* must be a name */
244 CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[i]), cmd.mMachine.asOutParam()), 1);
245 }
246 }
247 }
248 else if ( !strcmp(a->argv[i], "--name")
249 || !strcmp(a->argv[i], "-name"))
250 {
251 if (a->argc <= i + 1 || !*a->argv[i+1])
252 return errorArgument("Missing argument to '%s'", a->argv[i]);
253 i++;
254 cmd.mFilter.mName = a->argv[i];
255 }
256 else if ( !strcmp(a->argv[i], "--active")
257 || !strcmp(a->argv[i], "-active"))
258 {
259 if (a->argc <= i + 1)
260 return errorArgument("Missing argument to '%s'", a->argv[i]);
261 i++;
262 if (!strcmp(a->argv[i], "yes"))
263 cmd.mFilter.mActive = true;
264 else if (!strcmp(a->argv[i], "no"))
265 cmd.mFilter.mActive = false;
266 else
267 return errorArgument("Invalid --active argument '%s'", a->argv[i]);
268 }
269 else if ( !strcmp(a->argv[i], "--vendorid")
270 || !strcmp(a->argv[i], "-vendorid"))
271 {
272 if (a->argc <= i + 1)
273 return errorArgument("Missing argument to '%s'", a->argv[i]);
274 i++;
275 cmd.mFilter.mVendorId = a->argv[i];
276 }
277 else if ( !strcmp(a->argv[i], "--productid")
278 || !strcmp(a->argv[i], "-productid"))
279 {
280 if (a->argc <= i + 1)
281 return errorArgument("Missing argument to '%s'", a->argv[i]);
282 i++;
283 cmd.mFilter.mProductId = a->argv[i];
284 }
285 else if ( !strcmp(a->argv[i], "--revision")
286 || !strcmp(a->argv[i], "-revision"))
287 {
288 if (a->argc <= i + 1)
289 return errorArgument("Missing argument to '%s'", a->argv[i]);
290 i++;
291 cmd.mFilter.mRevision = a->argv[i];
292 }
293 else if ( !strcmp(a->argv[i], "--manufacturer")
294 || !strcmp(a->argv[i], "-manufacturer"))
295 {
296 if (a->argc <= i + 1)
297 return errorArgument("Missing argument to '%s'", a->argv[i]);
298 i++;
299 cmd.mFilter.mManufacturer = a->argv[i];
300 }
301 else if ( !strcmp(a->argv[i], "--product")
302 || !strcmp(a->argv[i], "-product"))
303 {
304 if (a->argc <= i + 1)
305 return errorArgument("Missing argument to '%s'", a->argv[i]);
306 i++;
307 cmd.mFilter.mProduct = a->argv[i];
308 }
309 else if ( !strcmp(a->argv[i], "--remote")
310 || !strcmp(a->argv[i], "-remote"))
311 {
312 if (a->argc <= i + 1)
313 return errorArgument("Missing argument to '%s'", a->argv[i]);
314 i++;
315 cmd.mFilter.mRemote = a->argv[i];
316 }
317 else if ( !strcmp(a->argv[i], "--serialnumber")
318 || !strcmp(a->argv[i], "-serialnumber"))
319 {
320 if (a->argc <= i + 1)
321 return errorArgument("Missing argument to '%s'", a->argv[i]);
322 i++;
323 cmd.mFilter.mSerialNumber = a->argv[i];
324 }
325 else if ( !strcmp(a->argv[i], "--maskedinterfaces")
326 || !strcmp(a->argv[i], "-maskedinterfaces"))
327 {
328 if (a->argc <= i + 1)
329 return errorArgument("Missing argument to '%s'", a->argv[i]);
330 i++;
331 uint32_t u32;
332 int vrc = RTStrToUInt32Full(a->argv[i], 0, &u32);
333 if (RT_FAILURE(vrc))
334 return errorArgument("Failed to convert the --maskedinterfaces value '%s' to a number, vrc=%Rrc", a->argv[i], vrc);
335 cmd.mFilter.mMaskedInterfaces = u32;
336 }
337 else if ( !strcmp(a->argv[i], "--action")
338 || !strcmp(a->argv[i], "-action"))
339 {
340 if (a->argc <= i + 1)
341 return errorArgument("Missing argument to '%s'", a->argv[i]);
342 i++;
343 if (!strcmp(a->argv[i], "ignore"))
344 cmd.mFilter.mAction = USBDeviceFilterAction_Ignore;
345 else if (!strcmp(a->argv[i], "hold"))
346 cmd.mFilter.mAction = USBDeviceFilterAction_Hold;
347 else
348 return errorArgument("Invalid USB filter action '%s'", a->argv[i]);
349 }
350 else
351 return errorSyntax(cmd.mAction == USBFilterCmd::Add ? USAGE_USBFILTER_ADD : USAGE_USBFILTER_MODIFY,
352 "Unknown option '%s'", a->argv[i]);
353 }
354
355 if (cmd.mAction == USBFilterCmd::Add)
356 {
357 // mandatory/forbidden options
358 if ( cmd.mFilter.mName.isEmpty()
359 ||
360 ( cmd.mGlobal
361 && cmd.mFilter.mAction == USBDeviceFilterAction_Null
362 )
363 || ( !cmd.mGlobal
364 && !cmd.mMachine)
365 || ( cmd.mGlobal
366 && cmd.mFilter.mRemote)
367 )
368 {
369 return errorSyntax(USAGE_USBFILTER_ADD, "Mandatory options not supplied");
370 }
371 }
372 break;
373 }
374
375 case USBFilterCmd::Remove:
376 {
377 /* at least: 0: command, 1: index, 2: --target, 3: <target value> */
378 if (a->argc < 4)
379 return errorSyntax(USAGE_USBFILTER_REMOVE, "Not enough parameters");
380
381 for (int i = 2; i < a->argc; i++)
382 {
383 if ( !strcmp(a->argv[i], "--target")
384 || !strcmp(a->argv[i], "-target"))
385 {
386 if (a->argc <= i + 1 || !*a->argv[i+1])
387 return errorArgument("Missing argument to '%s'", a->argv[i]);
388 i++;
389 if (!strcmp(a->argv[i], "global"))
390 cmd.mGlobal = true;
391 else
392 {
393 /* assume it's a UUID of a machine */
394 rc = a->virtualBox->GetMachine(Bstr(a->argv[i]), cmd.mMachine.asOutParam());
395 if (FAILED(rc) || !cmd.mMachine)
396 {
397 /* must be a name */
398 CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[i]), cmd.mMachine.asOutParam()), 1);
399 }
400 }
401 }
402 }
403
404 // mandatory options
405 if (!cmd.mGlobal && !cmd.mMachine)
406 return errorSyntax(USAGE_USBFILTER_REMOVE, "Mandatory options not supplied");
407
408 break;
409 }
410
411 default: break;
412 }
413
414 USBFilterCmd::USBFilter &f = cmd.mFilter;
415
416 ComPtr <IHost> host;
417 ComPtr <IUSBController> ctl;
418 if (cmd.mGlobal)
419 CHECK_ERROR_RET (a->virtualBox, COMGETTER(Host) (host.asOutParam()), 1);
420 else
421 {
422 Bstr uuid;
423 cmd.mMachine->COMGETTER(Id)(uuid.asOutParam());
424 /* open a session for the VM */
425 CHECK_ERROR_RET (a->virtualBox, OpenSession(a->session, uuid), 1);
426 /* get the mutable session machine */
427 a->session->COMGETTER(Machine)(cmd.mMachine.asOutParam());
428 /* and get the USB controller */
429 CHECK_ERROR_RET (cmd.mMachine, COMGETTER(USBController) (ctl.asOutParam()), 1);
430 }
431
432 switch (cmd.mAction)
433 {
434 case USBFilterCmd::Add:
435 {
436 if (cmd.mGlobal)
437 {
438 ComPtr <IHostUSBDeviceFilter> flt;
439 CHECK_ERROR_BREAK (host, CreateUSBDeviceFilter (f.mName, flt.asOutParam()));
440
441 if (!f.mActive.isNull())
442 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
443 if (!f.mVendorId.isEmpty())
444 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId));
445 if (!f.mProductId.isEmpty())
446 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId));
447 if (!f.mRevision.isEmpty())
448 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision));
449 if (!f.mManufacturer.isEmpty())
450 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer));
451 if (!f.mSerialNumber.isEmpty())
452 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber));
453 if (!f.mMaskedInterfaces.isNull())
454 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
455
456 if (f.mAction != USBDeviceFilterAction_Null)
457 CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));
458
459 CHECK_ERROR_BREAK (host, InsertUSBDeviceFilter (cmd.mIndex, flt));
460 }
461 else
462 {
463 ComPtr <IUSBDeviceFilter> flt;
464 CHECK_ERROR_BREAK (ctl, CreateDeviceFilter (f.mName, flt.asOutParam()));
465
466 if (!f.mActive.isNull())
467 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
468 if (!f.mVendorId.isEmpty())
469 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId));
470 if (!f.mProductId.isEmpty())
471 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId));
472 if (!f.mRevision.isEmpty())
473 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision));
474 if (!f.mManufacturer.isEmpty())
475 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer));
476 if (!f.mRemote.isEmpty())
477 CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote));
478 if (!f.mSerialNumber.isEmpty())
479 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber));
480 if (!f.mMaskedInterfaces.isNull())
481 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
482
483 CHECK_ERROR_BREAK (ctl, InsertDeviceFilter (cmd.mIndex, flt));
484 }
485 break;
486 }
487 case USBFilterCmd::Modify:
488 {
489 if (cmd.mGlobal)
490 {
491 SafeIfaceArray <IHostUSBDeviceFilter> coll;
492 CHECK_ERROR_BREAK (host, COMGETTER(USBDeviceFilters) (ComSafeArrayAsOutParam(coll)));
493
494 ComPtr <IHostUSBDeviceFilter> flt = coll[cmd.mIndex];
495
496 if (!f.mName.isEmpty())
497 CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName));
498 if (!f.mActive.isNull())
499 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
500 if (!f.mVendorId.isEmpty())
501 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId));
502 if (!f.mProductId.isEmpty())
503 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId));
504 if (!f.mRevision.isEmpty())
505 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision));
506 if (!f.mManufacturer.isEmpty())
507 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer));
508 if (!f.mSerialNumber.isEmpty())
509 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber));
510 if (!f.mMaskedInterfaces.isNull())
511 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
512
513 if (f.mAction != USBDeviceFilterAction_Null)
514 CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));
515 }
516 else
517 {
518 SafeIfaceArray <IUSBDeviceFilter> coll;
519 CHECK_ERROR_BREAK (ctl, COMGETTER(DeviceFilters) (ComSafeArrayAsOutParam(coll)));
520
521 ComPtr <IUSBDeviceFilter> flt = coll[cmd.mIndex];
522
523 if (!f.mName.isEmpty())
524 CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName));
525 if (!f.mActive.isNull())
526 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
527 if (!f.mVendorId.isEmpty())
528 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId));
529 if (!f.mProductId.isEmpty())
530 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId));
531 if (!f.mRevision.isEmpty())
532 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision));
533 if (!f.mManufacturer.isEmpty())
534 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer));
535 if (!f.mRemote.isEmpty())
536 CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote));
537 if (!f.mSerialNumber.isEmpty())
538 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber));
539 if (!f.mMaskedInterfaces.isNull())
540 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
541 }
542 break;
543 }
544 case USBFilterCmd::Remove:
545 {
546 if (cmd.mGlobal)
547 {
548 ComPtr <IHostUSBDeviceFilter> flt;
549 CHECK_ERROR_BREAK (host, RemoveUSBDeviceFilter (cmd.mIndex));
550 }
551 else
552 {
553 ComPtr <IUSBDeviceFilter> flt;
554 CHECK_ERROR_BREAK (ctl, RemoveDeviceFilter (cmd.mIndex, flt.asOutParam()));
555 }
556 break;
557 }
558 default:
559 break;
560 }
561
562 if (cmd.mMachine)
563 {
564 if (SUCCEEDED (rc))
565 {
566 /* commit the session */
567 CHECK_ERROR(cmd.mMachine, SaveSettings());
568 }
569 /* close the session */
570 a->session->Close();
571 }
572
573 return SUCCEEDED (rc) ? 0 : 1;
574}
575/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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