VirtualBox

source: vbox/trunk/src/VBox/Main/USBDeviceFilterImpl.cpp@ 3411

Last change on this file since 3411 was 2981, checked in by vboxsync, 17 years ago

InnoTek -> innotek: all the headers and comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.7 KB
Line 
1/** @file
2 *
3 * Implementation of VirtualBox COM components:
4 * USBDeviceFilter and HostUSBDeviceFilter
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23#include "USBDeviceFilterImpl.h"
24#include "USBControllerImpl.h"
25#include "MachineImpl.h"
26#include "HostImpl.h"
27#include "Logging.h"
28
29////////////////////////////////////////////////////////////////////////////////
30// USBDeviceFilter
31////////////////////////////////////////////////////////////////////////////////
32
33// constructor / destructor
34////////////////////////////////////////////////////////////////////////////////
35
36HRESULT USBDeviceFilter::FinalConstruct()
37{
38 return S_OK;
39}
40
41void USBDeviceFilter::FinalRelease()
42{
43 uninit();
44}
45
46// public initializer/uninitializer for internal purposes only
47////////////////////////////////////////////////////////////////////////////////
48
49/**
50 * Initializes the USB device filter object.
51 */
52HRESULT USBDeviceFilter::init (USBController *aParent,
53 INPTR BSTR aName, BOOL aActive,
54 INPTR BSTR aVendorId, INPTR BSTR aProductId,
55 INPTR BSTR aRevision,
56 INPTR BSTR aManufacturer, INPTR BSTR aProduct,
57 INPTR BSTR aSerialNumber,
58 INPTR BSTR aPort, INPTR BSTR aRemote)
59{
60 LogFlowMember (("USBDeviceFilter::init (%p)\n", aParent));
61
62 ComAssertRet (aParent && aName && *aName, E_INVALIDARG);
63
64 AutoLock alock (this);
65 ComAssertRet (!isReady(), E_UNEXPECTED);
66
67 mParent = aParent;
68
69 mData.allocate();
70 mData->mName = aName;
71 mData->mActive = aActive;
72
73 // initialize all filters to any match using null string
74 mData->mVendorId = NULL;
75 mData->mProductId = NULL;
76 mData->mRevision = NULL;
77 mData->mManufacturer = NULL;
78 mData->mProduct = NULL;
79 mData->mSerialNumber = NULL;
80 mData->mPort = NULL;
81 mData->mRemote = NULL;
82
83 mInList = false;
84
85 // use setters for the attributes below to reuse parsing errors handling
86 setReady (true);
87 HRESULT rc = S_OK;
88 do
89 {
90 rc = COMSETTER(VendorId) (aVendorId);
91 if (FAILED (rc))
92 break;
93 rc = COMSETTER(ProductId) (aProductId);
94 if (FAILED (rc))
95 break;
96 rc = COMSETTER(Revision) (aRevision);
97 if (FAILED (rc))
98 break;
99 rc = COMSETTER(Manufacturer) (aManufacturer);
100 if (FAILED (rc))
101 break;
102 rc = COMSETTER(Product) (aProduct);
103 if (FAILED (rc))
104 break;
105 rc = COMSETTER(SerialNumber) (aSerialNumber);
106 if (FAILED (rc))
107 break;
108 rc = COMSETTER(Port) (aPort);
109 if (FAILED (rc))
110 break;
111 rc = COMSETTER(Remote) (aRemote);
112 if (FAILED (rc))
113 break;
114 }
115 while (0);
116
117 if (SUCCEEDED (rc))
118 mParent->addDependentChild (this);
119 else
120 setReady (false);
121
122 return rc;
123}
124
125/**
126 * Initializes the USB device filter object (short version).
127 */
128HRESULT USBDeviceFilter::init (USBController *aParent, INPTR BSTR aName)
129{
130 LogFlowMember (("USBDeviceFilter::init (%p) [short]\n", aParent));
131
132 ComAssertRet (aParent && aName && *aName, E_INVALIDARG);
133
134 AutoLock alock (this);
135 ComAssertRet (!isReady(), E_UNEXPECTED);
136
137 mParent = aParent;
138 // mPeer is left null
139
140 mData.allocate();
141
142 mData->mName = aName;
143 mData->mActive = FALSE;
144
145 // initialize all filters to any match using null string
146 mData->mVendorId = NULL;
147 mData->mProductId = NULL;
148 mData->mRevision = NULL;
149 mData->mManufacturer = NULL;
150 mData->mProduct = NULL;
151 mData->mSerialNumber = NULL;
152 mData->mPort = NULL;
153 mData->mRemote = NULL;
154
155 mInList = false;
156
157 mParent->addDependentChild (this);
158
159 setReady (true);
160 return S_OK;
161}
162
163/**
164 * Initializes the object given another object
165 * (a kind of copy constructor). This object shares data with
166 * the object passed as an argument.
167 *
168 * @param aReshare
169 * When false, the original object will remain a data owner.
170 * Otherwise, data ownership will be transferred from the original
171 * object to this one.
172 *
173 * @note This object must be destroyed before the original object
174 * it shares data with is destroyed.
175 */
176HRESULT USBDeviceFilter::init (USBController *aParent, USBDeviceFilter *aThat,
177 bool aReshare /* = false */)
178{
179 LogFlowMember (("USBDeviceFilter::init (%p, %p): aReshare=%d\n",
180 aParent, aThat, aReshare));
181
182 ComAssertRet (aParent && aThat, E_INVALIDARG);
183
184 AutoLock alock (this);
185 ComAssertRet (!isReady(), E_UNEXPECTED);
186
187 mParent = aParent;
188
189 AutoLock thatlock (aThat);
190 if (aReshare)
191 {
192 aThat->mPeer = this;
193 mData.attach (aThat->mData);
194 }
195 else
196 {
197 mPeer = aThat;
198 mData.share (aThat->mData);
199 }
200
201 // the arbitrary ID field is not reset because
202 // the copy is a shadow of the original
203
204 mInList = aThat->mInList;
205
206 mParent->addDependentChild (this);
207
208 setReady (true);
209 return S_OK;
210}
211
212/**
213 * Initializes the guest object given another guest object
214 * (a kind of copy constructor). This object makes a private copy of data
215 * of the original object passed as an argument.
216 */
217HRESULT USBDeviceFilter::initCopy (USBController *aParent, USBDeviceFilter *aThat)
218{
219 LogFlowMember (("USBDeviceFilter::initCopy (%p, %p)\n", aParent, aThat));
220
221 ComAssertRet (aParent && aThat, E_INVALIDARG);
222
223 AutoLock alock (this);
224 ComAssertRet (!isReady(), E_UNEXPECTED);
225
226 mParent = aParent;
227 // mPeer is left null
228
229 AutoLock thatlock (aThat);
230 mData.attachCopy (aThat->mData);
231
232 // reset the arbitrary ID field
233 // (this field is something unique that two distinct objects, even if they
234 // are deep copies of each other, should not share)
235 mData->mId = NULL;
236
237 mInList = aThat->mInList;
238
239 mParent->addDependentChild (this);
240
241 setReady (true);
242 return S_OK;
243}
244
245/**
246 * Uninitializes the instance and sets the ready flag to FALSE.
247 * Called either from FinalRelease() or by the parent when it gets destroyed.
248 */
249void USBDeviceFilter::uninit()
250{
251 LogFlowMember (("USBDeviceFilter::uninit()\n"));
252
253 AutoLock alock (this);
254
255 LogFlowMember (("USBDeviceFilter::uninit(): isReady=%d\n", isReady()));
256
257 if (!isReady())
258 return;
259
260 mInList = false;
261
262 mData.free();
263
264 setReady (false);
265
266 alock.leave();
267 mParent->removeDependentChild (this);
268 alock.enter();
269
270 mPeer.setNull();
271 mParent.setNull();
272}
273
274// IUSBDeviceFilter properties
275////////////////////////////////////////////////////////////////////////////////
276
277STDMETHODIMP USBDeviceFilter::COMGETTER(Name) (BSTR *aName)
278{
279 if (!aName)
280 return E_POINTER;
281
282 AutoLock alock (this);
283 CHECK_READY();
284
285 mData->mName.cloneTo (aName);
286 return S_OK;
287}
288
289STDMETHODIMP USBDeviceFilter::COMSETTER(Name) (INPTR BSTR aName)
290{
291 if (!aName || *aName == 0)
292 return E_INVALIDARG;
293
294 AutoLock alock (this);
295 CHECK_READY();
296 CHECK_MACHINE_MUTABILITY (mParent->parent());
297
298 if (mData->mName != aName)
299 {
300 mData.backup();
301 mData->mName = aName;
302
303 // notify parent
304 alock.unlock();
305 return mParent->onDeviceFilterChange (this);
306 }
307
308 return S_OK;
309}
310
311STDMETHODIMP USBDeviceFilter::COMGETTER(Active) (BOOL *aActive)
312{
313 if (!aActive)
314 return E_POINTER;
315
316 AutoLock alock (this);
317 CHECK_READY();
318
319 *aActive = mData->mActive;
320 return S_OK;
321}
322
323STDMETHODIMP USBDeviceFilter::COMSETTER(Active) (BOOL aActive)
324{
325 AutoLock alock (this);
326 CHECK_READY();
327 CHECK_MACHINE_MUTABILITY (mParent->parent());
328
329 if (mData->mActive != aActive)
330 {
331 mData.backup();
332 mData->mActive = aActive;
333
334 // notify parent
335 alock.unlock();
336 return mParent->onDeviceFilterChange (this, TRUE /* aActiveChanged */);
337 }
338
339 return S_OK;
340}
341
342STDMETHODIMP USBDeviceFilter::COMGETTER(VendorId) (BSTR *aVendorId)
343{
344 if (!aVendorId)
345 return E_POINTER;
346
347 AutoLock alock (this);
348 CHECK_READY();
349
350 mData->mVendorId.string().cloneTo (aVendorId);
351 return S_OK;
352}
353
354STDMETHODIMP USBDeviceFilter::COMSETTER(VendorId) (INPTR BSTR aVendorId)
355{
356 AutoLock alock (this);
357 CHECK_READY();
358 CHECK_MACHINE_MUTABILITY (mParent->parent());
359
360 if (mData->mVendorId.string() != aVendorId)
361 {
362 Data::USHORTFilter flt = aVendorId;
363 ComAssertRet (!flt.isNull(), E_FAIL);
364 if (!flt.isValid())
365 return setError (E_INVALIDARG,
366 tr ("Vendor ID filter string '%ls' is not valid (error at position %d)"),
367 aVendorId, flt.errorPosition() + 1);
368#if defined (__WIN__)
369 // intervalic filters are temporarily disabled
370 if (!flt.first().isNull() && flt.first().isValid())
371 return setError (E_INVALIDARG,
372 tr ("'%ls': Intervalic filters are not currently available on this platform"),
373 aVendorId);
374#endif
375
376 mData.backup();
377 mData->mVendorId = flt;
378
379 // notify parent
380 alock.unlock();
381 return mParent->onDeviceFilterChange (this);
382 }
383
384 return S_OK;
385}
386
387STDMETHODIMP USBDeviceFilter::COMGETTER(ProductId) (BSTR *aProductId)
388{
389 if (!aProductId)
390 return E_POINTER;
391
392 AutoLock alock (this);
393 CHECK_READY();
394
395 mData->mProductId.string().cloneTo (aProductId);
396 return S_OK;
397}
398
399STDMETHODIMP USBDeviceFilter::COMSETTER(ProductId) (INPTR BSTR aProductId)
400{
401 AutoLock alock (this);
402 CHECK_READY();
403 CHECK_MACHINE_MUTABILITY (mParent->parent());
404
405 if (mData->mProductId.string() != aProductId)
406 {
407 Data::USHORTFilter flt = aProductId;
408 ComAssertRet (!flt.isNull(), E_FAIL);
409 if (!flt.isValid())
410 return setError (E_INVALIDARG,
411 tr ("Product ID filter string '%ls' is not valid (error at position %d)"),
412 aProductId, flt.errorPosition() + 1);
413#if defined (__WIN__)
414 // intervalic filters are temporarily disabled
415 if (!flt.first().isNull() && flt.first().isValid())
416 return setError (E_INVALIDARG,
417 tr ("'%ls': Intervalic filters are not currently available on this platform"),
418 aProductId);
419#endif
420
421 mData.backup();
422 mData->mProductId = flt;
423
424 // notify parent
425 alock.unlock();
426 return mParent->onDeviceFilterChange (this);
427 }
428
429 return S_OK;
430}
431
432STDMETHODIMP USBDeviceFilter::COMGETTER(Revision) (BSTR *aRevision)
433{
434 if (!aRevision)
435 return E_POINTER;
436
437 AutoLock alock (this);
438 CHECK_READY();
439
440 mData->mRevision.string().cloneTo (aRevision);
441 return S_OK;
442}
443
444STDMETHODIMP USBDeviceFilter::COMSETTER(Revision) (INPTR BSTR aRevision)
445{
446 AutoLock alock (this);
447 CHECK_READY();
448 CHECK_MACHINE_MUTABILITY (mParent->parent());
449
450 if (mData->mRevision.string() != aRevision)
451 {
452 Data::USHORTFilter flt = aRevision;
453 ComAssertRet (!flt.isNull(), E_FAIL);
454 if (!flt.isValid())
455 return setError (E_INVALIDARG,
456 tr ("Revision filter string '%ls' is not valid (error at position %d)"),
457 aRevision, flt.errorPosition() + 1);
458#if defined (__WIN__)
459 // intervalic filters are temporarily disabled
460 if (!flt.first().isNull() && flt.first().isValid())
461 return setError (E_INVALIDARG,
462 tr ("'%ls': Intervalic filters are not currently available on this platform"),
463 aRevision);
464#endif
465
466 mData.backup();
467 mData->mRevision = flt;
468
469 // notify parent
470 alock.unlock();
471 return mParent->onDeviceFilterChange (this);
472 }
473
474 return S_OK;
475}
476
477STDMETHODIMP USBDeviceFilter::COMGETTER(Manufacturer) (BSTR *aManufacturer)
478{
479 if (!aManufacturer)
480 return E_POINTER;
481
482 AutoLock alock (this);
483 CHECK_READY();
484
485 mData->mManufacturer.string().cloneTo (aManufacturer);
486 return S_OK;
487}
488
489STDMETHODIMP USBDeviceFilter::COMSETTER(Manufacturer) (INPTR BSTR aManufacturer)
490{
491 AutoLock alock (this);
492 CHECK_READY();
493 CHECK_MACHINE_MUTABILITY (mParent->parent());
494
495 if (mData->mManufacturer.string() != aManufacturer)
496 {
497 Data::BstrFilter flt = aManufacturer;
498 ComAssertRet (!flt.isNull(), E_FAIL);
499 if (!flt.isValid())
500 return setError (E_INVALIDARG,
501 tr ("Manufacturer filter string '%ls' is not valid (error at position %d)"),
502 aManufacturer, flt.errorPosition() + 1);
503
504 mData.backup();
505 mData->mManufacturer = flt;
506
507 // notify parent
508 alock.unlock();
509 return mParent->onDeviceFilterChange (this);
510 }
511
512 return S_OK;
513}
514
515STDMETHODIMP USBDeviceFilter::COMGETTER(Product) (BSTR *aProduct)
516{
517 if (!aProduct)
518 return E_POINTER;
519
520 AutoLock alock (this);
521 CHECK_READY();
522
523 mData->mProduct.string().cloneTo (aProduct);
524 return S_OK;
525}
526
527STDMETHODIMP USBDeviceFilter::COMSETTER(Product) (INPTR BSTR aProduct)
528{
529 AutoLock alock (this);
530 CHECK_READY();
531 CHECK_MACHINE_MUTABILITY (mParent->parent());
532
533 if (mData->mProduct.string() != aProduct)
534 {
535 Data::BstrFilter flt = aProduct;
536 ComAssertRet (!flt.isNull(), E_FAIL);
537 if (!flt.isValid())
538 return setError (E_INVALIDARG,
539 tr ("Product filter string '%ls' is not valid (error at position %d)"),
540 aProduct, flt.errorPosition() + 1);
541
542 mData.backup();
543 mData->mProduct = flt;
544
545 // notify parent
546 alock.unlock();
547 return mParent->onDeviceFilterChange (this);
548 }
549
550 return S_OK;
551}
552
553STDMETHODIMP USBDeviceFilter::COMGETTER(SerialNumber) (BSTR *aSerialNumber)
554{
555 if (!aSerialNumber)
556 return E_POINTER;
557
558 AutoLock alock (this);
559 CHECK_READY();
560
561 mData->mSerialNumber.string().cloneTo (aSerialNumber);
562 return S_OK;
563}
564
565STDMETHODIMP USBDeviceFilter::COMSETTER(SerialNumber) (INPTR BSTR aSerialNumber)
566{
567 AutoLock alock (this);
568 CHECK_READY();
569 CHECK_MACHINE_MUTABILITY (mParent->parent());
570
571 if (mData->mSerialNumber.string() != aSerialNumber)
572 {
573 Data::BstrFilter flt = aSerialNumber;
574 ComAssertRet (!flt.isNull(), E_FAIL);
575 if (!flt.isValid())
576 return setError (E_INVALIDARG,
577 tr ("Serial number filter string '%ls' is not valid (error at position %d)"),
578 aSerialNumber, flt.errorPosition() + 1);
579
580 mData.backup();
581 mData->mSerialNumber = flt;
582
583 // notify parent
584 alock.unlock();
585 return mParent->onDeviceFilterChange (this);
586 }
587
588 return S_OK;
589}
590
591STDMETHODIMP USBDeviceFilter::COMGETTER(Port) (BSTR *aPort)
592{
593 if (!aPort)
594 return E_POINTER;
595
596 AutoLock alock (this);
597 CHECK_READY();
598
599 mData->mPort.string().cloneTo (aPort);
600 return S_OK;
601}
602
603STDMETHODIMP USBDeviceFilter::COMSETTER(Port) (INPTR BSTR aPort)
604{
605 AutoLock alock (this);
606 CHECK_READY();
607 CHECK_MACHINE_MUTABILITY (mParent->parent());
608
609 if (mData->mPort.string() != aPort)
610 {
611 Data::USHORTFilter flt = aPort;
612 ComAssertRet (!flt.isNull(), E_FAIL);
613 if (!flt.isValid())
614 return setError (E_INVALIDARG,
615 tr ("Port number filter string '%ls' is not valid (error at position %d)"),
616 aPort, flt.errorPosition() + 1);
617#if defined (__WIN__)
618 // intervalic filters are temporarily disabled
619 if (!flt.first().isNull() && flt.first().isValid())
620 return setError (E_INVALIDARG,
621 tr ("'%ls': Intervalic filters are not currently available on this platform"),
622 aPort);
623#endif
624
625 mData.backup();
626 mData->mPort = flt;
627
628 // notify parent
629 alock.unlock();
630 return mParent->onDeviceFilterChange (this);
631 }
632
633 return S_OK;
634}
635
636STDMETHODIMP USBDeviceFilter::COMGETTER(Remote) (BSTR *aRemote)
637{
638 if (!aRemote)
639 return E_POINTER;
640
641 AutoLock alock (this);
642 CHECK_READY();
643
644 mData->mRemote.string().cloneTo (aRemote);
645 return S_OK;
646}
647
648STDMETHODIMP USBDeviceFilter::COMSETTER(Remote) (INPTR BSTR aRemote)
649{
650 AutoLock alock (this);
651 CHECK_READY();
652 CHECK_MACHINE_MUTABILITY (mParent->parent());
653
654 if (mData->mRemote.string() != aRemote)
655 {
656 Data::BOOLFilter flt = aRemote;
657 ComAssertRet (!flt.isNull(), E_FAIL);
658 if (!flt.isValid())
659 return setError (E_INVALIDARG,
660 tr ("Remote state filter string '%ls' is not valid (error at position %d)"),
661 aRemote, flt.errorPosition() + 1);
662
663 mData.backup();
664 mData->mRemote = flt;
665
666 // notify parent
667 alock.unlock();
668 return mParent->onDeviceFilterChange (this);
669 }
670
671 return S_OK;
672}
673
674// public methods only for internal purposes
675////////////////////////////////////////////////////////////////////////////////
676
677void USBDeviceFilter::commit()
678{
679 AutoLock alock (this);
680 if (mData.isBackedUp())
681 {
682 mData.commit();
683 if (mPeer)
684 {
685 // attach new data to the peer and reshare it
686 AutoLock peerlock (mPeer);
687 mPeer->mData.attach (mData);
688 }
689 }
690}
691
692/**
693 * Cancels sharing (if any) by making an independent copy of data.
694 * This operation also resets this object's peer to NULL.
695 */
696void USBDeviceFilter::unshare()
697{
698 AutoLock alock (this);
699 if (mData.isShared())
700 {
701 if (!mData.isBackedUp())
702 mData.backup();
703 mData.commit();
704 }
705 mPeer.setNull();
706}
707
708////////////////////////////////////////////////////////////////////////////////
709// HostUSBDeviceFilter
710////////////////////////////////////////////////////////////////////////////////
711
712// constructor / destructor
713////////////////////////////////////////////////////////////////////////////////
714
715HRESULT HostUSBDeviceFilter::FinalConstruct()
716{
717 return S_OK;
718}
719
720void HostUSBDeviceFilter::FinalRelease()
721{
722 uninit();
723}
724
725// public initializer/uninitializer for internal purposes only
726////////////////////////////////////////////////////////////////////////////////
727
728/**
729 * Initializes the USB device filter object.
730 */
731HRESULT HostUSBDeviceFilter::init (Host *aParent,
732 INPTR BSTR aName, BOOL aActive,
733 INPTR BSTR aVendorId, INPTR BSTR aProductId,
734 INPTR BSTR aRevision,
735 INPTR BSTR aManufacturer, INPTR BSTR aProduct,
736 INPTR BSTR aSerialNumber,
737 INPTR BSTR aPort,
738 USBDeviceFilterAction_T aAction)
739{
740 LogFlowMember (("HostUSBDeviceFilter::init(): isReady=%d\n", isReady()));
741
742 ComAssertRet (aParent && aName && *aName, E_INVALIDARG);
743
744 AutoLock alock (this);
745 ComAssertRet (!isReady(), E_UNEXPECTED);
746
747 mParent = aParent;
748
749 mData.allocate();
750 mData->mName = aName;
751 mData->mActive = aActive;
752 mData->mAction = aAction;
753
754 // initialize all filters to any match using null string
755 mData->mVendorId = NULL;
756 mData->mProductId = NULL;
757 mData->mRevision = NULL;
758 mData->mManufacturer = NULL;
759 mData->mProduct = NULL;
760 mData->mSerialNumber = NULL;
761 mData->mPort = NULL;
762 mData->mRemote = NULL;
763
764 mInList = false;
765
766 // use setters for the attributes below to reuse parsing errors handling
767 setReady (true);
768 HRESULT rc;
769 do
770 {
771 rc = COMSETTER(VendorId) (aVendorId);
772 if (FAILED (rc))
773 break;
774 rc = COMSETTER(ProductId) (aProductId);
775 if (FAILED (rc))
776 break;
777 rc = COMSETTER(Revision) (aRevision);
778 if (FAILED (rc))
779 break;
780 rc = COMSETTER(Manufacturer) (aManufacturer);
781 if (FAILED (rc))
782 break;
783 rc = COMSETTER(Product) (aProduct);
784 if (FAILED (rc))
785 break;
786 rc = COMSETTER(SerialNumber) (aSerialNumber);
787 if (FAILED (rc))
788 break;
789 rc = COMSETTER(Port) (aPort);
790 if (FAILED (rc))
791 break;
792 }
793 while (0);
794
795 if (SUCCEEDED (rc))
796 mParent->addDependentChild (this);
797 else
798 setReady (false);
799
800 return rc;
801}
802
803/**
804 * Initializes the USB device filter object (short version).
805 */
806HRESULT HostUSBDeviceFilter::init (Host *aParent, INPTR BSTR aName)
807{
808 LogFlowMember (("HostUSBDeviceFilter::init(): isReady=%d\n", isReady()));
809
810 ComAssertRet (aParent && aName && *aName, E_INVALIDARG);
811
812 AutoLock alock (this);
813 ComAssertRet (!isReady(), E_UNEXPECTED);
814
815 mParent = aParent;
816
817 mData.allocate();
818 mData->mName = aName;
819 mData->mActive = FALSE;
820 mData->mAction = USBDeviceFilterAction_USBDeviceFilterIgnore;
821
822 mInList = false;
823
824 // initialize all filters using null string (any match)
825 mData->mVendorId = NULL;
826 mData->mProductId = NULL;
827 mData->mRevision = NULL;
828 mData->mManufacturer = NULL;
829 mData->mProduct = NULL;
830 mData->mSerialNumber = NULL;
831 mData->mPort = NULL;
832 mData->mRemote = NULL;
833
834 mParent->addDependentChild (this);
835
836 setReady (true);
837 return S_OK;
838}
839
840/**
841 * Uninitializes the instance and sets the ready flag to FALSE.
842 * Called either from FinalRelease() or by the parent when it gets destroyed.
843 */
844void HostUSBDeviceFilter::uninit()
845{
846 LogFlowMember (("HostUSBDeviceFilter::uninit()\n"));
847
848 AutoLock alock (this);
849
850 LogFlowMember (("HostUSBDeviceFilter::uninit(): isReady=%d\n", isReady()));
851
852 if (!isReady())
853 return;
854
855 mInList = false;
856
857 mData.free();
858
859 setReady (false);
860
861 alock.leave();
862 mParent->removeDependentChild (this);
863 alock.enter();
864
865 mParent.setNull();
866}
867
868// IUSBDeviceFilter properties
869////////////////////////////////////////////////////////////////////////////////
870
871STDMETHODIMP HostUSBDeviceFilter::COMGETTER(Name) (BSTR *aName)
872{
873 if (!aName)
874 return E_POINTER;
875
876 AutoLock alock (this);
877 CHECK_READY();
878
879 mData->mName.cloneTo (aName);
880 return S_OK;
881}
882
883STDMETHODIMP HostUSBDeviceFilter::COMSETTER(Name) (INPTR BSTR aName)
884{
885 if (!aName || *aName == 0)
886 return E_INVALIDARG;
887
888 AutoLock alock (this);
889 CHECK_READY();
890
891 if (mData->mName != aName)
892 {
893 mData->mName = aName;
894
895 // notify parent
896 alock.unlock();
897 return mParent->onUSBDeviceFilterChange (this);
898 }
899
900 return S_OK;
901}
902
903STDMETHODIMP HostUSBDeviceFilter::COMGETTER(Active) (BOOL *aActive)
904{
905 if (!aActive)
906 return E_POINTER;
907
908 AutoLock alock (this);
909 CHECK_READY();
910
911 *aActive = mData->mActive;
912 return S_OK;
913}
914
915STDMETHODIMP HostUSBDeviceFilter::COMSETTER(Active) (BOOL aActive)
916{
917 AutoLock alock (this);
918 CHECK_READY();
919
920 if (mData->mActive != aActive)
921 {
922 mData->mActive = aActive;
923
924 // notify parent
925 alock.unlock();
926 return mParent->onUSBDeviceFilterChange (this, TRUE /* aActiveChanged */);
927 }
928
929 return S_OK;
930}
931
932STDMETHODIMP HostUSBDeviceFilter::COMGETTER(VendorId) (BSTR *aVendorId)
933{
934 if (!aVendorId)
935 return E_POINTER;
936
937 AutoLock alock (this);
938 CHECK_READY();
939
940 mData->mVendorId.string().cloneTo (aVendorId);
941 return S_OK;
942}
943
944STDMETHODIMP HostUSBDeviceFilter::COMSETTER(VendorId) (INPTR BSTR aVendorId)
945{
946 AutoLock alock (this);
947 CHECK_READY();
948
949 if (mData->mVendorId.string() != aVendorId)
950 {
951 Data::USHORTFilter flt = aVendorId;
952 ComAssertRet (!flt.isNull(), E_FAIL);
953 if (!flt.isValid())
954 return setError (E_INVALIDARG,
955 tr ("Vendor ID filter string '%ls' is not valid (error at position %d)"),
956 aVendorId, flt.errorPosition() + 1);
957#if defined (__WIN__)
958 // intervalic filters are temporarily disabled
959 if (!flt.first().isNull() && flt.first().isValid())
960 return setError (E_INVALIDARG,
961 tr ("'%ls': Intervalic filters are not currently available on this platform"),
962 aVendorId);
963#endif
964
965 mData->mVendorId = flt;
966
967 // notify parent
968 alock.unlock();
969 return mParent->onUSBDeviceFilterChange (this);
970 }
971
972 return S_OK;
973}
974
975STDMETHODIMP HostUSBDeviceFilter::COMGETTER(ProductId) (BSTR *aProductId)
976{
977 if (!aProductId)
978 return E_POINTER;
979
980 AutoLock alock (this);
981 CHECK_READY();
982
983 mData->mProductId.string().cloneTo (aProductId);
984 return S_OK;
985}
986
987STDMETHODIMP HostUSBDeviceFilter::COMSETTER(ProductId) (INPTR BSTR aProductId)
988{
989 AutoLock alock (this);
990 CHECK_READY();
991
992 if (mData->mProductId.string() != aProductId)
993 {
994 Data::USHORTFilter flt = aProductId;
995 ComAssertRet (!flt.isNull(), E_FAIL);
996 if (!flt.isValid())
997 return setError (E_INVALIDARG,
998 tr ("Product ID filter string '%ls' is not valid (error at position %d)"),
999 aProductId, flt.errorPosition() + 1);
1000#if defined (__WIN__)
1001 // intervalic filters are temporarily disabled
1002 if (!flt.first().isNull() && flt.first().isValid())
1003 return setError (E_INVALIDARG,
1004 tr ("'%ls': Intervalic filters are not currently available on this platform"),
1005 aProductId);
1006#endif
1007
1008 mData->mProductId = flt;
1009
1010 // notify parent
1011 alock.unlock();
1012 return mParent->onUSBDeviceFilterChange (this);
1013 }
1014
1015 return S_OK;
1016}
1017
1018STDMETHODIMP HostUSBDeviceFilter::COMGETTER(Revision) (BSTR *aRevision)
1019{
1020 if (!aRevision)
1021 return E_POINTER;
1022
1023 AutoLock alock (this);
1024 CHECK_READY();
1025
1026 mData->mRevision.string().cloneTo (aRevision);
1027 return S_OK;
1028}
1029
1030STDMETHODIMP HostUSBDeviceFilter::COMSETTER(Revision) (INPTR BSTR aRevision)
1031{
1032 AutoLock alock (this);
1033 CHECK_READY();
1034
1035 if (mData->mRevision.string() != aRevision)
1036 {
1037 Data::USHORTFilter flt = aRevision;
1038 ComAssertRet (!flt.isNull(), E_FAIL);
1039 if (!flt.isValid())
1040 return setError (E_INVALIDARG,
1041 tr ("Revision filter string '%ls' is not valid (error at position %d)"),
1042 aRevision, flt.errorPosition() + 1);
1043#if defined (__WIN__)
1044 // intervalic filters are temporarily disabled
1045 if (!flt.first().isNull() && flt.first().isValid())
1046 return setError (E_INVALIDARG,
1047 tr ("'%ls': Intervalic filters are not currently available on this platform"),
1048 aRevision);
1049#endif
1050
1051 mData->mRevision = flt;
1052
1053 // notify parent
1054 alock.unlock();
1055 return mParent->onUSBDeviceFilterChange (this);
1056 }
1057
1058 return S_OK;
1059}
1060
1061STDMETHODIMP HostUSBDeviceFilter::COMGETTER(Manufacturer) (BSTR *aManufacturer)
1062{
1063 if (!aManufacturer)
1064 return E_POINTER;
1065
1066 AutoLock alock (this);
1067 CHECK_READY();
1068
1069 mData->mManufacturer.string().cloneTo (aManufacturer);
1070 return S_OK;
1071}
1072
1073STDMETHODIMP HostUSBDeviceFilter::COMSETTER(Manufacturer) (INPTR BSTR aManufacturer)
1074{
1075 AutoLock alock (this);
1076 CHECK_READY();
1077
1078 if (mData->mManufacturer.string() != aManufacturer)
1079 {
1080 Data::BstrFilter flt = aManufacturer;
1081 ComAssertRet (!flt.isNull(), E_FAIL);
1082 if (!flt.isValid())
1083 return setError (E_INVALIDARG,
1084 tr ("Manufacturer filter string '%ls' is not valid (error at position %d)"),
1085 aManufacturer, flt.errorPosition() + 1);
1086
1087 mData->mManufacturer = flt;
1088
1089 // notify parent
1090 alock.unlock();
1091 return mParent->onUSBDeviceFilterChange (this);
1092 }
1093
1094 return S_OK;
1095}
1096
1097STDMETHODIMP HostUSBDeviceFilter::COMGETTER(Product) (BSTR *aProduct)
1098{
1099 if (!aProduct)
1100 return E_POINTER;
1101
1102 AutoLock alock (this);
1103 CHECK_READY();
1104
1105 mData->mProduct.string().cloneTo (aProduct);
1106 return S_OK;
1107}
1108
1109STDMETHODIMP HostUSBDeviceFilter::COMSETTER(Product) (INPTR BSTR aProduct)
1110{
1111 AutoLock alock (this);
1112 CHECK_READY();
1113
1114 if (mData->mProduct.string() != aProduct)
1115 {
1116 Data::BstrFilter flt = aProduct;
1117 ComAssertRet (!flt.isNull(), E_FAIL);
1118 if (!flt.isValid())
1119 return setError (E_INVALIDARG,
1120 tr ("Product filter string '%ls' is not valid (error at position %d)"),
1121 aProduct, flt.errorPosition() + 1);
1122
1123 mData->mProduct = flt;
1124
1125 // notify parent
1126 alock.unlock();
1127 return mParent->onUSBDeviceFilterChange (this);
1128 }
1129
1130 return S_OK;
1131}
1132
1133STDMETHODIMP HostUSBDeviceFilter::COMGETTER(SerialNumber) (BSTR *aSerialNumber)
1134{
1135 if (!aSerialNumber)
1136 return E_POINTER;
1137
1138 AutoLock alock (this);
1139 CHECK_READY();
1140
1141 mData->mSerialNumber.string().cloneTo (aSerialNumber);
1142 return S_OK;
1143}
1144
1145STDMETHODIMP HostUSBDeviceFilter::COMSETTER(SerialNumber) (INPTR BSTR aSerialNumber)
1146{
1147 AutoLock alock (this);
1148 CHECK_READY();
1149
1150 if (mData->mSerialNumber.string() != aSerialNumber)
1151 {
1152 Data::BstrFilter flt = aSerialNumber;
1153 ComAssertRet (!flt.isNull(), E_FAIL);
1154 if (!flt.isValid())
1155 return setError (E_INVALIDARG,
1156 tr ("Serial number filter string '%ls' is not valid (error at position %d)"),
1157 aSerialNumber, flt.errorPosition() + 1);
1158
1159 mData->mSerialNumber = flt;
1160
1161 // notify parent
1162 alock.unlock();
1163 return mParent->onUSBDeviceFilterChange (this);
1164 }
1165
1166 return S_OK;
1167}
1168
1169STDMETHODIMP HostUSBDeviceFilter::COMGETTER(Port) (BSTR *aPort)
1170{
1171 if (!aPort)
1172 return E_POINTER;
1173
1174 AutoLock alock (this);
1175 CHECK_READY();
1176
1177 mData->mPort.string().cloneTo (aPort);
1178 return S_OK;
1179}
1180
1181STDMETHODIMP HostUSBDeviceFilter::COMSETTER(Port) (INPTR BSTR aPort)
1182{
1183 AutoLock alock (this);
1184 CHECK_READY();
1185
1186 if (mData->mPort.string() != aPort)
1187 {
1188 Data::USHORTFilter flt = aPort;
1189 ComAssertRet (!flt.isNull(), E_FAIL);
1190 if (!flt.isValid())
1191 return setError (E_INVALIDARG,
1192 tr ("Port number filter string '%ls' is not valid (error at position %d)"),
1193 aPort, flt.errorPosition() + 1);
1194#if defined (__WIN__)
1195 // intervalic filters are temporarily disabled
1196 if (!flt.first().isNull() && flt.first().isValid())
1197 return setError (E_INVALIDARG,
1198 tr ("'%ls': Intervalic filters are not currently available on this platform"),
1199 aPort);
1200#endif
1201
1202 mData->mPort = flt;
1203
1204 // notify parent
1205 alock.unlock();
1206 return mParent->onUSBDeviceFilterChange (this);
1207 }
1208
1209 return S_OK;
1210}
1211
1212STDMETHODIMP HostUSBDeviceFilter::COMGETTER(Remote) (BSTR *aRemote)
1213{
1214 if (!aRemote)
1215 return E_POINTER;
1216
1217 AutoLock alock (this);
1218 CHECK_READY();
1219
1220 mData->mRemote.string().cloneTo (aRemote);
1221 return S_OK;
1222}
1223
1224STDMETHODIMP HostUSBDeviceFilter::COMSETTER(Remote) (INPTR BSTR aRemote)
1225{
1226 return setError (E_NOTIMPL,
1227 tr ("The remote state filter is not supported by "
1228 "IHostUSBDeviceFilter objects"));
1229}
1230
1231// IHostUSBDeviceFilter properties
1232////////////////////////////////////////////////////////////////////////////////
1233
1234STDMETHODIMP HostUSBDeviceFilter::COMGETTER(Action) (USBDeviceFilterAction_T *aAction)
1235{
1236 if (!aAction)
1237 return E_POINTER;
1238
1239 AutoLock alock (this);
1240 CHECK_READY();
1241
1242 *aAction = mData->mAction;
1243 return S_OK;
1244}
1245
1246STDMETHODIMP HostUSBDeviceFilter::COMSETTER(Action) (USBDeviceFilterAction_T aAction)
1247{
1248 AutoLock alock (this);
1249 CHECK_READY();
1250
1251 if (mData->mAction != aAction)
1252 {
1253 mData->mAction = aAction;
1254
1255 // notify parent
1256 alock.unlock();
1257 return mParent->onUSBDeviceFilterChange (this);
1258 }
1259
1260 return S_OK;
1261}
1262
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use