VirtualBox

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

Last change on this file since 53624 was 50914, checked in by vboxsync, 11 years ago

6813 src-all/ExtPackManagerImpl.cpp

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.3 KB
Line 
1/* $Id: HostVideoInputDeviceImpl.cpp 50914 2014-03-27 19:07:53Z vboxsync $ */
2/** @file
3 *
4 * Host video capture device implementation.
5 */
6
7/*
8 * Copyright (C) 2013 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 m.name.setNull();
78 m.path.setNull();
79 m.alias.setNull();
80
81 /* Enclose the state transition Ready->InUninit->NotReady */
82 AutoUninitSpan autoUninitSpan(this);
83 if (autoUninitSpan.uninitDone())
84 return;
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 = VINF_SUCCESS;
135 RTLDRMOD hmod = NIL_RTLDRMOD;
136
137 RTERRINFOSTATIC ErrInfo;
138 RTErrInfoInitStatic(&ErrInfo);
139 if (RTPathHavePath(pszPath))
140 rc = SUPR3HardenedLdrLoadPlugIn(pszPath, &hmod, &ErrInfo.Core);
141 else
142 rc = VERR_INVALID_PARAMETER;
143 if (RT_SUCCESS(rc))
144 {
145 static const char *pszSymbol = "VBoxHostWebcamList";
146 rc = RTLdrGetSymbol(hmod, pszSymbol, (void **)ppfn);
147
148 if (RT_FAILURE(rc) && rc != VERR_SYMBOL_NOT_FOUND)
149 LogRel(("Resolving symbol '%s': %Rrc\n", pszSymbol, rc));
150 }
151 else
152 {
153 LogRel(("Loading the library '%s': %Rrc\n", pszPath, rc));
154 if (RTErrInfoIsSet(&ErrInfo.Core))
155 LogRel((" %s\n", ErrInfo.Core.pszMsg));
156
157 hmod = NIL_RTLDRMOD;
158 }
159
160 if (RT_SUCCESS(rc))
161 {
162 *phmod = hmod;
163 }
164 else
165 {
166 if (hmod != NIL_RTLDRMOD)
167 {
168 RTLdrClose(hmod);
169 hmod = NIL_RTLDRMOD;
170 }
171 }
172
173 return rc;
174}
175
176static const Utf8Str strExtPackPuel("Oracle VM VirtualBox Extension Pack");
177
178static HRESULT fillDeviceList(VirtualBox *pVirtualBox, HostVideoInputDeviceList *pList)
179{
180 HRESULT hr;
181 Utf8Str strLibrary;
182
183#ifdef VBOX_WITH_EXTPACK
184 ExtPackManager *pExtPackMgr = pVirtualBox->i_getExtPackManager();
185 hr = pExtPackMgr->i_getLibraryPathForExtPack("VBoxHostWebcam", &strExtPackPuel, &strLibrary);
186#else
187 hr = E_NOTIMPL;
188#endif
189
190 if (SUCCEEDED(hr))
191 {
192 PFNVBOXHOSTWEBCAMLIST pfn = NULL;
193 RTLDRMOD hmod = NIL_RTLDRMOD;
194 int rc = loadHostWebcamLibrary(strLibrary.c_str(), &hmod, &pfn);
195
196 LogRel(("Load [%s] rc %Rrc\n", strLibrary.c_str(), rc));
197
198 if (RT_SUCCESS(rc))
199 {
200 uint64_t u64Result = S_OK;
201 rc = pfn(hostWebcamAdd, pList, &u64Result);
202 Log(("VBoxHostWebcamList rc %Rrc, result 0x%08X\n", rc, u64Result));
203 if (RT_FAILURE(rc))
204 {
205 hr = (HRESULT)u64Result;
206 }
207
208 RTLdrClose(hmod);
209 hmod = NIL_RTLDRMOD;
210 }
211
212 if (SUCCEEDED(hr))
213 {
214 if (RT_FAILURE(rc))
215 hr = pVirtualBox->setError(VBOX_E_IPRT_ERROR,
216 "Failed to get webcam list: %Rrc", rc);
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