VirtualBox

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

Last change on this file since 74897 was 73003, checked in by vboxsync, 6 years ago

Main: Use setErrorBoth when we've got a VBox status code handy. (The COM status codes aren't too specfic and this may help us decode error messages and provide an alternative to strstr for API clients. setErrorBoth isn't new, btw.)

  • 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 73003 2018-07-09 11:09:32Z 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 vrc = loadHostWebcamLibrary(strLibrary.c_str(), &hmod, &pfn);
187
188 LogRel(("Load [%s] vrc=%Rrc\n", strLibrary.c_str(), vrc));
189
190 if (RT_SUCCESS(vrc))
191 {
192 uint64_t u64Result = S_OK;
193 vrc = pfn(hostWebcamAdd, pList, &u64Result);
194 Log(("VBoxHostWebcamList vrc %Rrc, result 0x%08X\n", vrc, u64Result));
195 if (RT_FAILURE(vrc))
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(vrc))
207 hr = pVirtualBox->setErrorBoth(VBOX_E_IPRT_ERROR, vrc, "Failed to get webcam list: %Rrc", vrc);
208 }
209 }
210
211 return hr;
212}
213
214/* static */ HRESULT HostVideoInputDevice::queryHostDevices(VirtualBox *pVirtualBox, HostVideoInputDeviceList *pList)
215{
216 HRESULT hr = fillDeviceList(pVirtualBox, pList);
217
218 if (FAILED(hr))
219 {
220 pList->clear();
221 }
222
223 return hr;
224}
225
226/* 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