VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/HostVideoInputDeviceImpl.cpp

Last change on this file was 98293, checked in by vboxsync, 16 months ago

Main/src-server: hr -> hrc. bugref:10223

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.4 KB
RevLine 
[48578]1/* $Id: HostVideoInputDeviceImpl.cpp 98293 2023-01-25 01:22:39Z vboxsync $ */
2/** @file
3 * Host video capture device implementation.
4 */
5
6/*
[98103]7 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
[48578]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[48578]26 */
27
[76592]28#define LOG_GROUP LOG_GROUP_MAIN_HOSTVIDEOINPUTDEVICE
[48607]29#include "HostVideoInputDeviceImpl.h"
[76592]30#include "LoggingNew.h"
[49132]31#include "VirtualBoxImpl.h"
32#ifdef VBOX_WITH_EXTPACK
33# include "ExtPackManagerImpl.h"
[48600]34#endif
35
[76389]36#include <iprt/err.h>
[49132]37#include <iprt/ldr.h>
38#include <iprt/path.h>
39
40#include <VBox/sup.h>
41
[48578]42/*
[48607]43 * HostVideoInputDevice implementation.
[48578]44 */
[48607]45DEFINE_EMPTY_CTOR_DTOR(HostVideoInputDevice)
[48578]46
[48607]47HRESULT HostVideoInputDevice::FinalConstruct()
[48578]48{
49 return BaseFinalConstruct();
50}
51
[48607]52void HostVideoInputDevice::FinalRelease()
[48578]53{
54 uninit();
55
56 BaseFinalRelease();
57}
58
59/*
60 * Initializes the instance.
61 */
[48607]62HRESULT HostVideoInputDevice::init(const com::Utf8Str &name, const com::Utf8Str &path, const com::Utf8Str &alias)
[48578]63{
64 LogFlowThisFunc(("\n"));
65
66 /* Enclose the state transition NotReady->InInit->Ready */
67 AutoInitSpan autoInitSpan(this);
68 AssertReturn(autoInitSpan.isOk(), E_FAIL);
69
70 m.name = name;
71 m.path = path;
72 m.alias = alias;
73
74 /* Confirm a successful initialization */
75 autoInitSpan.setSucceeded();
76
77 return S_OK;
78}
79
80/*
81 * Uninitializes the instance.
82 * Called either from FinalRelease() or by the parent when it gets destroyed.
83 */
[48607]84void HostVideoInputDevice::uninit()
[48578]85{
86 LogFlowThisFunc(("\n"));
87
88 /* Enclose the state transition Ready->InUninit->NotReady */
89 AutoUninitSpan autoUninitSpan(this);
90 if (autoUninitSpan.uninitDone())
91 return;
[55710]92
93 m.name.setNull();
94 m.path.setNull();
95 m.alias.setNull();
[48578]96}
97
[48607]98static HRESULT hostVideoInputDeviceAdd(HostVideoInputDeviceList *pList,
99 const com::Utf8Str &name,
100 const com::Utf8Str &path,
101 const com::Utf8Str &alias)
[48578]102{
[48607]103 ComObjPtr<HostVideoInputDevice> obj;
[98293]104 HRESULT hrc = obj.createObject();
105 if (SUCCEEDED(hrc))
[48578]106 {
[98293]107 hrc = obj->init(name, path, alias);
108 if (SUCCEEDED(hrc))
[48600]109 pList->push_back(obj);
110 }
[98293]111 return hrc;
[48600]112}
[48578]113
[49132]114static DECLCALLBACK(int) hostWebcamAdd(void *pvUser,
115 const char *pszName,
116 const char *pszPath,
117 const char *pszAlias,
118 uint64_t *pu64Result)
[48600]119{
[49132]120 HostVideoInputDeviceList *pList = (HostVideoInputDeviceList *)pvUser;
[98293]121 HRESULT hrc = hostVideoInputDeviceAdd(pList, pszName, pszPath, pszAlias);
122 if (FAILED(hrc))
[48600]123 {
[98293]124 *pu64Result = (uint64_t)hrc;
[49132]125 return VERR_NOT_SUPPORTED;
[48578]126 }
[49132]127 return VINF_SUCCESS;
[48578]128}
129
[49132]130/** @todo These typedefs must be in a header. */
[85121]131typedef DECLCALLBACKTYPE(int, FNVBOXHOSTWEBCAMADD,(void *pvUser,
132 const char *pszName,
133 const char *pszPath,
134 const char *pszAlias,
135 uint64_t *pu64Result));
[49132]136typedef FNVBOXHOSTWEBCAMADD *PFNVBOXHOSTWEBCAMADD;
[48600]137
[85121]138typedef DECLCALLBACKTYPE(int, FNVBOXHOSTWEBCAMLIST,(PFNVBOXHOSTWEBCAMADD pfnWebcamAdd,
139 void *pvUser,
140 uint64_t *pu64WebcamAddResult));
[49132]141typedef FNVBOXHOSTWEBCAMLIST *PFNVBOXHOSTWEBCAMLIST;
[48600]142
[91514]143
144/*
145 * Work around clang being unhappy about PFNVBOXHOSTWEBCAMLIST
146 * ("exception specifications are not allowed beyond a single level of
147 * indirection"). The original comment for 13.0 check said: "assuming
148 * this issue will be fixed eventually". Well, 13.0 is now out, and
149 * it was not.
150 */
151#define CLANG_EXCEPTION_SPEC_HACK (RT_CLANG_PREREQ(11, 0) /* && !RT_CLANG_PREREQ(13, 0) */)
152
153#if CLANG_EXCEPTION_SPEC_HACK
[85252]154static int loadHostWebcamLibrary(const char *pszPath, RTLDRMOD *phmod, void **ppfn)
155#else
[49132]156static int loadHostWebcamLibrary(const char *pszPath, RTLDRMOD *phmod, PFNVBOXHOSTWEBCAMLIST *ppfn)
[85252]157#endif
[49132]158{
[98288]159 int vrc;
[49132]160 if (RTPathHavePath(pszPath))
161 {
[63147]162 RTLDRMOD hmod = NIL_RTLDRMOD;
163 RTERRINFOSTATIC ErrInfo;
[98288]164 vrc = SUPR3HardenedLdrLoadPlugIn(pszPath, &hmod, RTErrInfoInitStatic(&ErrInfo));
165 if (RT_SUCCESS(vrc))
[63147]166 {
167 static const char s_szSymbol[] = "VBoxHostWebcamList";
[98288]168 vrc = RTLdrGetSymbol(hmod, s_szSymbol, (void **)ppfn);
169 if (RT_SUCCESS(vrc))
[63147]170 *phmod = hmod;
171 else
172 {
[98288]173 if (vrc != VERR_SYMBOL_NOT_FOUND)
174 LogRel(("Resolving symbol '%s': %Rrc\n", s_szSymbol, vrc));
[63147]175 RTLdrClose(hmod);
176 hmod = NIL_RTLDRMOD;
177 }
178 }
179 else
180 {
[98288]181 LogRel(("Loading the library '%s': %Rrc\n", pszPath, vrc));
[63147]182 if (RTErrInfoIsSet(&ErrInfo.Core))
183 LogRel((" %s\n", ErrInfo.Core.pszMsg));
184 }
[49132]185 }
186 else
187 {
[63147]188 LogRel(("Loading the library '%s': No path! Refusing to try loading it!\n", pszPath));
[98288]189 vrc = VERR_INVALID_PARAMETER;
[49132]190 }
[98288]191 return vrc;
[49132]192}
[48600]193
194
[49132]195static HRESULT fillDeviceList(VirtualBox *pVirtualBox, HostVideoInputDeviceList *pList)
196{
197 Utf8Str strLibrary;
198#ifdef VBOX_WITH_EXTPACK
[50355]199 ExtPackManager *pExtPackMgr = pVirtualBox->i_getExtPackManager();
[98293]200 HRESULT hrc = pExtPackMgr->i_getLibraryPathForExtPack("VBoxHostWebcam", ORACLE_PUEL_EXTPACK_NAME, &strLibrary);
[49132]201#else
[98293]202 HRESULT hrc = E_NOTIMPL;
[49132]203#endif
[48600]204
[98293]205 if (SUCCEEDED(hrc))
[48600]206 {
[49132]207 PFNVBOXHOSTWEBCAMLIST pfn = NULL;
208 RTLDRMOD hmod = NIL_RTLDRMOD;
[91514]209#if CLANG_EXCEPTION_SPEC_HACK
[85252]210 int vrc = loadHostWebcamLibrary(strLibrary.c_str(), &hmod, (void **)&pfn);
211#else
[73003]212 int vrc = loadHostWebcamLibrary(strLibrary.c_str(), &hmod, &pfn);
[85252]213#endif
[49132]214
[73003]215 LogRel(("Load [%s] vrc=%Rrc\n", strLibrary.c_str(), vrc));
[49132]216
[73003]217 if (RT_SUCCESS(vrc))
[48600]218 {
[49132]219 uint64_t u64Result = S_OK;
[73003]220 vrc = pfn(hostWebcamAdd, pList, &u64Result);
[85252]221 Log(("VBoxHostWebcamList vrc %Rrc, result 0x%08RX64\n", vrc, u64Result));
[73003]222 if (RT_FAILURE(vrc))
[98293]223 hrc = (HRESULT)u64Result;
[49132]224
225 RTLdrClose(hmod);
226 hmod = NIL_RTLDRMOD;
[48600]227 }
[49132]228
[98293]229 if (SUCCEEDED(hrc))
[48600]230 {
[73003]231 if (RT_FAILURE(vrc))
[98293]232 hrc = pVirtualBox->setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
233 HostVideoInputDevice::tr("Failed to get webcam list: %Rrc"), vrc);
[48600]234 }
235 }
[49132]236
[98293]237 return hrc;
[48600]238}
239
[49132]240/* static */ HRESULT HostVideoInputDevice::queryHostDevices(VirtualBox *pVirtualBox, HostVideoInputDeviceList *pList)
[48600]241{
[98293]242 HRESULT hrc = fillDeviceList(pVirtualBox, pList);
243 if (FAILED(hrc))
[48600]244 pList->clear();
[98293]245 return hrc;
[48600]246}
247
[48578]248/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use