VirtualBox

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

Last change on this file since 69859 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

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