VirtualBox

source: vbox/trunk/src/VBox/Main/ExtPackManagerImpl.cpp@ 33477

Last change on this file since 33477 was 33477, checked in by vboxsync, 14 years ago

build fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
Line 
1/* $Id: ExtPackManagerImpl.cpp 33477 2010-10-26 19:44:31Z vboxsync $ */
2/** @file
3 * VirtualBox Main - interface for Extension Packs, VBoxSVC & VBoxC.
4 */
5
6/*
7 * Copyright (C) 2010 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
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include "ExtPackManagerImpl.h"
23
24#include <iprt/dir.h>
25#include <iprt/ldr.h>
26#include <iprt/param.h>
27#include <iprt/path.h>
28
29#include <VBox/com/array.h>
30#include <VBox/log.h>
31#include "AutoCaller.h"
32
33
34/*******************************************************************************
35* Structures and Typedefs *
36*******************************************************************************/
37/**
38 * Private extension pack data.
39 */
40struct ExtPack::Data
41{
42 /** @name IExtPack Attributes.
43 * @{ */
44 /** The name. */
45 Utf8Str strName;
46 /** The version string. */
47 Utf8Str strVersion;
48 /** The revision. */
49 uint32_t uRevision;
50 /** Whether it's usable or not. */
51 bool fUsable;
52 /** Why it is unusable. */
53 Utf8Str strWhyUnusable;
54 /** @} */
55
56 /** Where the extension pack is located. */
57 Utf8Str strPath;
58 /** The module handle of the main extension pack module. */
59 RTLDRMOD hMainMod;
60};
61
62/** List of extension packs. */
63typedef std::list< ComObjPtr<ExtPack> > ExtPackList;
64
65/**
66 * Private extension pack manager data.
67 */
68struct ExtPackManager::Data
69{
70 /** Where the directory where the extension packs are installed. */
71 Utf8Str strBasePath;
72 /** The list of installed extension packs. */
73 ExtPackList llInstalledExtPacks;
74};
75
76
77DEFINE_EMPTY_CTOR_DTOR(ExtPack)
78
79/**
80 * Called by ComObjPtr::createObject when creating the object.
81 *
82 * Just initialize the basic object state, do the rest in init().
83 *
84 * @returns S_OK.
85 */
86HRESULT ExtPack::FinalConstruct()
87{
88 m = NULL;
89 return S_OK;
90}
91
92/**
93 * Initializes the extension pack by reading its file.
94 *
95 * @returns COM status code.
96 * @param a_pszName The name of the extension pack. This is also the
97 * name of the subdirector under @a a_pszParentDir
98 * where the extension pack is installed.
99 * @param a_pszParentDir The parent directory.
100 */
101HRESULT ExtPack::init(const char *a_pszName, const char *a_pszParentDir)
102{
103 /*
104 * Figure out where we live and allocate+initialize our private data.
105 */
106 char szDir[RTPATH_MAX];
107 int vrc = RTPathJoin(szDir, sizeof(szDir), a_pszParentDir, a_pszName);
108 AssertLogRelRCReturn(vrc, E_FAIL);
109
110 m = new Data;
111 m->strName = a_pszName;
112 m->strVersion = "";
113 m->uRevision = 0;
114 m->fUsable = false;
115 m->strWhyUnusable = tr("ExtPack::init failed");
116
117 m->strPath = szDir;
118 m->hMainMod = NIL_RTLDRMOD;
119
120 /*
121 * Read the description file.
122 */
123
124
125 return S_OK;
126}
127
128/**
129 * COM cruft.
130 */
131void ExtPack::FinalRelease()
132{
133 uninit();
134}
135
136/**
137 * Do the actual cleanup.
138 */
139void ExtPack::uninit()
140{
141 /* Enclose the state transition Ready->InUninit->NotReady */
142 AutoUninitSpan autoUninitSpan(this);
143 if (!autoUninitSpan.uninitDone() && m != NULL)
144 {
145 if (m->hMainMod != NIL_RTLDRMOD)
146 {
147 RTLdrClose(m->hMainMod);
148 m->hMainMod = NIL_RTLDRMOD;
149 }
150
151 delete m;
152 m = NULL;
153 }
154}
155
156
157
158
159STDMETHODIMP ExtPack::COMGETTER(Name)(BSTR *a_pbstrName)
160{
161 CheckComArgOutPointerValid(a_pbstrName);
162
163 AutoCaller autoCaller(this);
164 HRESULT hrc = autoCaller.rc();
165 if (SUCCEEDED(hrc))
166 m->strName.cloneTo(a_pbstrName);
167 return hrc;
168}
169
170STDMETHODIMP ExtPack::COMGETTER(Version)(BSTR *a_pbstrVersion)
171{
172 CheckComArgOutPointerValid(a_pbstrVersion);
173
174 AutoCaller autoCaller(this);
175 HRESULT hrc = autoCaller.rc();
176 if (SUCCEEDED(hrc))
177 m->strVersion.cloneTo(a_pbstrVersion);
178 return hrc;
179}
180
181STDMETHODIMP ExtPack::COMGETTER(Revision)(ULONG *a_puRevision)
182{
183 CheckComArgOutPointerValid(a_puRevision);
184
185 AutoCaller autoCaller(this);
186 HRESULT hrc = autoCaller.rc();
187 if (SUCCEEDED(hrc))
188 *a_puRevision = m->uRevision;
189 return hrc;
190}
191
192STDMETHODIMP ExtPack::COMGETTER(Usable)(BOOL *a_pfUsable)
193{
194 CheckComArgOutPointerValid(a_pfUsable);
195
196 AutoCaller autoCaller(this);
197 HRESULT hrc = autoCaller.rc();
198 if (SUCCEEDED(hrc))
199 *a_pfUsable = m->fUsable;
200 return hrc;
201}
202
203STDMETHODIMP ExtPack::COMGETTER(WhyUnusable)(BSTR *a_pbstrWhy)
204{
205 CheckComArgOutPointerValid(a_pbstrWhy);
206
207 AutoCaller autoCaller(this);
208 HRESULT hrc = autoCaller.rc();
209 if (SUCCEEDED(hrc))
210 m->strWhyUnusable.cloneTo(a_pbstrWhy);
211 return hrc;
212}
213
214
215
216void *ExtPack::getCallbackTable()
217{
218 return NULL;
219}
220
221
222
223
224DEFINE_EMPTY_CTOR_DTOR(ExtPackManager)
225
226/**
227 * Called by ComObjPtr::createObject when creating the object.
228 *
229 * Just initialize the basic object state, do the rest in init().
230 *
231 * @returns S_OK.
232 */
233HRESULT ExtPackManager::FinalConstruct()
234{
235 m = NULL;
236 return S_OK;
237}
238
239/**
240 * Initializes the extension pack manager.
241 *
242 * @returns COM status code.
243 */
244HRESULT ExtPackManager::init()
245{
246 /*
247 * Figure some stuff out before creating the instance data.
248 */
249 char szBasePath[RTPATH_MAX];
250 int rc = RTPathAppPrivateArch(szBasePath, sizeof(szBasePath));
251 AssertLogRelRCReturn(rc, E_FAIL);
252 rc = RTPathAppend(szBasePath, sizeof(szBasePath), "ExtensionPacks");
253 AssertLogRelRCReturn(rc, E_FAIL);
254
255 /*
256 * Allocate and initialize the instance data.
257 */
258 m = new Data;
259 m->strBasePath = szBasePath;
260
261 /*
262 * Go looking for extensions. The RTDirOpen may fail if nothing has been
263 * installed yet, or if root is paranoid and has revoked our access to them.
264 *
265 * We ASSUME that there are no files, directories or stuff in the directory
266 * that exceed the max name length in RTDIRENTRYEX.
267 */
268 PRTDIR pDir;
269 int vrc = RTDirOpen(&pDir, szBasePath);
270 if (RT_FAILURE(vrc))
271 return S_OK;
272 HRESULT hrc = S_OK;
273 for (;;)
274 {
275 RTDIRENTRYEX Entry;
276 vrc = RTDirReadEx(pDir, &Entry, NULL /*pcbDirEntry*/, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
277 if (RT_FAILURE(vrc))
278 {
279 AssertLogRelMsg(vrc == VERR_NO_MORE_FILES, ("%Rrc\n", vrc));
280 break;
281 }
282 if ( RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode)
283 && strcmp(Entry.szName, ".") != 0
284 && strcmp(Entry.szName, "..") != 0 )
285 {
286 /*
287 * All directories are extensions, the shall be nothing but
288 * extensions in this subdirectory.
289 */
290 ComObjPtr<ExtPack> NewExtPack;
291 HRESULT hrc2 = NewExtPack.createObject();
292 if (SUCCEEDED(hrc2))
293 hrc2 = NewExtPack->init(Entry.szName, szBasePath);
294 if (SUCCEEDED(hrc2))
295 m->llInstalledExtPacks.push_back(NewExtPack);
296 else if (SUCCEEDED(rc))
297 hrc = hrc2;
298 }
299 }
300 RTDirClose(pDir);
301
302 return hrc;
303}
304
305/**
306 * COM cruft.
307 */
308void ExtPackManager::FinalRelease()
309{
310 uninit();
311}
312
313/**
314 * Do the actual cleanup.
315 */
316void ExtPackManager::uninit()
317{
318 /* Enclose the state transition Ready->InUninit->NotReady */
319 AutoUninitSpan autoUninitSpan(this);
320 if (!autoUninitSpan.uninitDone() && m != NULL)
321 {
322 /** @todo do unload notifications */
323
324 delete m;
325 m = NULL;
326 }
327}
328
329
330STDMETHODIMP ExtPackManager::COMGETTER(InstalledExtPacks)(ComSafeArrayOut(IExtPack *, a_paExtPacks))
331{
332 CheckComArgSafeArrayNotNull(a_paExtPacks);
333
334 AutoCaller autoCaller(this);
335 HRESULT hrc = autoCaller.rc();
336 if (SUCCEEDED(hrc))
337 {
338 AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
339
340 SafeIfaceArray<IExtPack> SaExtPacks(m->llInstalledExtPacks);
341 SaExtPacks.detachTo(ComSafeArrayOutArg(a_paExtPacks));
342 }
343
344 return hrc;
345}
346
347STDMETHODIMP ExtPackManager::Find(IN_BSTR a_bstrName, IExtPack **a_pExtPack)
348{
349 CheckComArgNotNull(a_bstrName);
350 CheckComArgOutPointerValid(a_pExtPack);
351 Utf8Str strName(a_bstrName);
352
353 AutoCaller autoCaller(this);
354 HRESULT hrc = autoCaller.rc();
355 if (SUCCEEDED(hrc))
356 {
357 AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
358
359 hrc = VBOX_E_OBJECT_NOT_FOUND;
360 for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
361 it != m->llInstalledExtPacks.end();
362 it++)
363 {
364 ExtPack::Data *pExtPackData = (*it)->m;
365 if ( pExtPackData
366 && pExtPackData->strName.compare(strName) == 0)
367 {
368 (*it).queryInterfaceTo(a_pExtPack);
369 hrc = S_OK;
370 break;
371 }
372 }
373 }
374
375 return hrc;
376}
377
378STDMETHODIMP ExtPackManager::Install(IN_BSTR a_bstrTarball, BSTR *a_pbstrName)
379{
380 NOREF(a_bstrTarball); NOREF(a_pbstrName);
381 return E_NOTIMPL;
382}
383
384STDMETHODIMP ExtPackManager::Uninstall(IN_BSTR a_bstrName, BOOL a_fForcedRemoval)
385{
386 NOREF(a_bstrName); NOREF(a_fForcedRemoval);
387 return E_NOTIMPL;
388}
389
390
391
392int ExtPackManager::callAllConfigHooks(IConsole *a_pConsole, PVM a_pVM)
393{
394 NOREF(a_pConsole); NOREF(a_pVM);
395 return VINF_SUCCESS;
396}
397
398int ExtPackManager::callAllNewMachineHooks(IMachine *a_pMachine)
399{
400 NOREF(a_pMachine);
401 return VINF_SUCCESS;
402}
403
404/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette