VirtualBox

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

Last change on this file since 78093 was 76592, checked in by vboxsync, 6 years ago

Main: Don't use Logging.h.

  • 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 76592 2019-01-01 20:13:07Z vboxsync $ */
2/** @file
3 * Host video capture device implementation.
4 */
5
6/*
7 * Copyright (C) 2013-2019 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 DECLCALLBACK(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 DECLCALLBACK(int) FNVBOXHOSTWEBCAMLIST(PFNVBOXHOSTWEBCAMADD pfnWebcamAdd,
129 void *pvUser,
130 uint64_t *pu64WebcamAddResult);
131typedef FNVBOXHOSTWEBCAMLIST *PFNVBOXHOSTWEBCAMLIST;
132
133static int loadHostWebcamLibrary(const char *pszPath, RTLDRMOD *phmod, PFNVBOXHOSTWEBCAMLIST *ppfn)
134{
135 int rc;
136 if (RTPathHavePath(pszPath))
137 {
138 RTLDRMOD hmod = NIL_RTLDRMOD;
139 RTERRINFOSTATIC ErrInfo;
140 rc = SUPR3HardenedLdrLoadPlugIn(pszPath, &hmod, RTErrInfoInitStatic(&ErrInfo));
141 if (RT_SUCCESS(rc))
142 {
143 static const char s_szSymbol[] = "VBoxHostWebcamList";
144 rc = RTLdrGetSymbol(hmod, s_szSymbol, (void **)ppfn);
145 if (RT_SUCCESS(rc))
146 *phmod = hmod;
147 else
148 {
149 if (rc != VERR_SYMBOL_NOT_FOUND)
150 LogRel(("Resolving symbol '%s': %Rrc\n", s_szSymbol, rc));
151 RTLdrClose(hmod);
152 hmod = NIL_RTLDRMOD;
153 }
154 }
155 else
156 {
157 LogRel(("Loading the library '%s': %Rrc\n", pszPath, rc));
158 if (RTErrInfoIsSet(&ErrInfo.Core))
159 LogRel((" %s\n", ErrInfo.Core.pszMsg));
160 }
161 }
162 else
163 {
164 LogRel(("Loading the library '%s': No path! Refusing to try loading it!\n", pszPath));
165 rc = VERR_INVALID_PARAMETER;
166 }
167 return rc;
168}
169
170
171static HRESULT fillDeviceList(VirtualBox *pVirtualBox, HostVideoInputDeviceList *pList)
172{
173 HRESULT hr;
174 Utf8Str strLibrary;
175
176#ifdef VBOX_WITH_EXTPACK
177 ExtPackManager *pExtPackMgr = pVirtualBox->i_getExtPackManager();
178 hr = pExtPackMgr->i_getLibraryPathForExtPack("VBoxHostWebcam", ORACLE_PUEL_EXTPACK_NAME, &strLibrary);
179#else
180 hr = E_NOTIMPL;
181#endif
182
183 if (SUCCEEDED(hr))
184 {
185 PFNVBOXHOSTWEBCAMLIST pfn = NULL;
186 RTLDRMOD hmod = NIL_RTLDRMOD;
187 int vrc = loadHostWebcamLibrary(strLibrary.c_str(), &hmod, &pfn);
188
189 LogRel(("Load [%s] vrc=%Rrc\n", strLibrary.c_str(), vrc));
190
191 if (RT_SUCCESS(vrc))
192 {
193 uint64_t u64Result = S_OK;
194 vrc = pfn(hostWebcamAdd, pList, &u64Result);
195 Log(("VBoxHostWebcamList vrc %Rrc, result 0x%08X\n", vrc, u64Result));
196 if (RT_FAILURE(vrc))
197 {
198 hr = (HRESULT)u64Result;
199 }
200
201 RTLdrClose(hmod);
202 hmod = NIL_RTLDRMOD;
203 }
204
205 if (SUCCEEDED(hr))
206 {
207 if (RT_FAILURE(vrc))
208 hr = pVirtualBox->setErrorBoth(VBOX_E_IPRT_ERROR, vrc, "Failed to get webcam list: %Rrc", vrc);
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