VirtualBox

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

Last change on this file since 85672 was 85252, checked in by vboxsync, 4 years ago

Main/HostVideoInputDeviceImpl.cpp: Workaround for Clang 11 nothrow/PPFN issue. bugref:9790

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: HostVideoInputDeviceImpl.cpp 85252 2020-07-11 23:26:04Z vboxsync $ */
2/** @file
3 * Host video capture device implementation.
4 */
5
6/*
7 * Copyright (C) 2013-2020 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#define LOG_GROUP LOG_GROUP_MAIN_HOSTVIDEOINPUTDEVICE
19#include "HostVideoInputDeviceImpl.h"
20#include "LoggingNew.h"
21#include "VirtualBoxImpl.h"
22#ifdef VBOX_WITH_EXTPACK
23# include "ExtPackManagerImpl.h"
24#endif
25
26#include <iprt/err.h>
27#include <iprt/ldr.h>
28#include <iprt/path.h>
29
30#include <VBox/sup.h>
31
32/*
33 * HostVideoInputDevice implementation.
34 */
35DEFINE_EMPTY_CTOR_DTOR(HostVideoInputDevice)
36
37HRESULT HostVideoInputDevice::FinalConstruct()
38{
39 return BaseFinalConstruct();
40}
41
42void HostVideoInputDevice::FinalRelease()
43{
44 uninit();
45
46 BaseFinalRelease();
47}
48
49/*
50 * Initializes the instance.
51 */
52HRESULT HostVideoInputDevice::init(const com::Utf8Str &name, const com::Utf8Str &path, const com::Utf8Str &alias)
53{
54 LogFlowThisFunc(("\n"));
55
56 /* Enclose the state transition NotReady->InInit->Ready */
57 AutoInitSpan autoInitSpan(this);
58 AssertReturn(autoInitSpan.isOk(), E_FAIL);
59
60 m.name = name;
61 m.path = path;
62 m.alias = alias;
63
64 /* Confirm a successful initialization */
65 autoInitSpan.setSucceeded();
66
67 return S_OK;
68}
69
70/*
71 * Uninitializes the instance.
72 * Called either from FinalRelease() or by the parent when it gets destroyed.
73 */
74void HostVideoInputDevice::uninit()
75{
76 LogFlowThisFunc(("\n"));
77
78 /* Enclose the state transition Ready->InUninit->NotReady */
79 AutoUninitSpan autoUninitSpan(this);
80 if (autoUninitSpan.uninitDone())
81 return;
82
83 m.name.setNull();
84 m.path.setNull();
85 m.alias.setNull();
86}
87
88static HRESULT hostVideoInputDeviceAdd(HostVideoInputDeviceList *pList,
89 const com::Utf8Str &name,
90 const com::Utf8Str &path,
91 const com::Utf8Str &alias)
92{
93 ComObjPtr<HostVideoInputDevice> obj;
94 HRESULT hr = obj.createObject();
95 if (SUCCEEDED(hr))
96 {
97 hr = obj->init(name, path, alias);
98 if (SUCCEEDED(hr))
99 pList->push_back(obj);
100 }
101 return hr;
102}
103
104static DECLCALLBACK(int) hostWebcamAdd(void *pvUser,
105 const char *pszName,
106 const char *pszPath,
107 const char *pszAlias,
108 uint64_t *pu64Result)
109{
110 HostVideoInputDeviceList *pList = (HostVideoInputDeviceList *)pvUser;
111 HRESULT hr = hostVideoInputDeviceAdd(pList, pszName, pszPath, pszAlias);
112 if (FAILED(hr))
113 {
114 *pu64Result = (uint64_t)hr;
115 return VERR_NOT_SUPPORTED;
116 }
117 return VINF_SUCCESS;
118}
119
120/** @todo These typedefs must be in a header. */
121typedef DECLCALLBACKTYPE(int, FNVBOXHOSTWEBCAMADD,(void *pvUser,
122 const char *pszName,
123 const char *pszPath,
124 const char *pszAlias,
125 uint64_t *pu64Result));
126typedef FNVBOXHOSTWEBCAMADD *PFNVBOXHOSTWEBCAMADD;
127
128typedef DECLCALLBACKTYPE(int, FNVBOXHOSTWEBCAMLIST,(PFNVBOXHOSTWEBCAMADD pfnWebcamAdd,
129 void *pvUser,
130 uint64_t *pu64WebcamAddResult));
131typedef FNVBOXHOSTWEBCAMLIST *PFNVBOXHOSTWEBCAMLIST;
132
133#if RT_CLANG_PREREQ(11, 0) && !RT_CLANG_PREREQ(13, 0) /*assuming this issue will be fixed eventually*/
134static int loadHostWebcamLibrary(const char *pszPath, RTLDRMOD *phmod, void **ppfn)
135#else
136static int loadHostWebcamLibrary(const char *pszPath, RTLDRMOD *phmod, PFNVBOXHOSTWEBCAMLIST *ppfn)
137#endif
138{
139 int rc;
140 if (RTPathHavePath(pszPath))
141 {
142 RTLDRMOD hmod = NIL_RTLDRMOD;
143 RTERRINFOSTATIC ErrInfo;
144 rc = SUPR3HardenedLdrLoadPlugIn(pszPath, &hmod, RTErrInfoInitStatic(&ErrInfo));
145 if (RT_SUCCESS(rc))
146 {
147 static const char s_szSymbol[] = "VBoxHostWebcamList";
148 rc = RTLdrGetSymbol(hmod, s_szSymbol, (void **)ppfn);
149 if (RT_SUCCESS(rc))
150 *phmod = hmod;
151 else
152 {
153 if (rc != VERR_SYMBOL_NOT_FOUND)
154 LogRel(("Resolving symbol '%s': %Rrc\n", s_szSymbol, rc));
155 RTLdrClose(hmod);
156 hmod = NIL_RTLDRMOD;
157 }
158 }
159 else
160 {
161 LogRel(("Loading the library '%s': %Rrc\n", pszPath, rc));
162 if (RTErrInfoIsSet(&ErrInfo.Core))
163 LogRel((" %s\n", ErrInfo.Core.pszMsg));
164 }
165 }
166 else
167 {
168 LogRel(("Loading the library '%s': No path! Refusing to try loading it!\n", pszPath));
169 rc = VERR_INVALID_PARAMETER;
170 }
171 return rc;
172}
173
174
175static HRESULT fillDeviceList(VirtualBox *pVirtualBox, HostVideoInputDeviceList *pList)
176{
177 HRESULT hr;
178 Utf8Str strLibrary;
179
180#ifdef VBOX_WITH_EXTPACK
181 ExtPackManager *pExtPackMgr = pVirtualBox->i_getExtPackManager();
182 hr = pExtPackMgr->i_getLibraryPathForExtPack("VBoxHostWebcam", ORACLE_PUEL_EXTPACK_NAME, &strLibrary);
183#else
184 hr = E_NOTIMPL;
185#endif
186
187 if (SUCCEEDED(hr))
188 {
189 PFNVBOXHOSTWEBCAMLIST pfn = NULL;
190 RTLDRMOD hmod = NIL_RTLDRMOD;
191#if RT_CLANG_PREREQ(11, 0) && !RT_CLANG_PREREQ(13, 0) /*assuming this issue will be fixed eventually*/
192 int vrc = loadHostWebcamLibrary(strLibrary.c_str(), &hmod, (void **)&pfn);
193#else
194 int vrc = loadHostWebcamLibrary(strLibrary.c_str(), &hmod, &pfn);
195#endif
196
197 LogRel(("Load [%s] vrc=%Rrc\n", strLibrary.c_str(), vrc));
198
199 if (RT_SUCCESS(vrc))
200 {
201 uint64_t u64Result = S_OK;
202 vrc = pfn(hostWebcamAdd, pList, &u64Result);
203 Log(("VBoxHostWebcamList vrc %Rrc, result 0x%08RX64\n", vrc, u64Result));
204 if (RT_FAILURE(vrc))
205 {
206 hr = (HRESULT)u64Result;
207 }
208
209 RTLdrClose(hmod);
210 hmod = NIL_RTLDRMOD;
211 }
212
213 if (SUCCEEDED(hr))
214 {
215 if (RT_FAILURE(vrc))
216 hr = pVirtualBox->setErrorBoth(VBOX_E_IPRT_ERROR, vrc, "Failed to get webcam list: %Rrc", vrc);
217 }
218 }
219
220 return hr;
221}
222
223/* static */ HRESULT HostVideoInputDevice::queryHostDevices(VirtualBox *pVirtualBox, HostVideoInputDeviceList *pList)
224{
225 HRESULT hr = fillDeviceList(pVirtualBox, pList);
226
227 if (FAILED(hr))
228 {
229 pList->clear();
230 }
231
232 return hr;
233}
234
235/* 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