Re: CR: Removal of persistent plugin data
Tad Yeager <[email protected]>
| Newsgroups | gmane.comp.multimedia.helix.devel |
|---|---|
| Message-ID | <[email protected]> |
Proposed new interface is now called IHXMediaPlatformCleaner and has three methods: HRESULT RemoveAllPreferences(void) HRESULT RemovePersistentPluginData(void) HRESULT RemoveNamedPreference(const char* pszPreferenceRootName) The MediaPlatform shouldn't have to be restarted. Generally, if plugin data is missing from preferences, Plugin2Handler will regenerate it. The exception that necessitates the change we're reviewing: if VerifyChecksum_ fails in Plugin2Handler::ReadPluginInfoFast (or ReadPluginInfoSlow), PluginHandlerData\FileInfoX is regenerated but PluginHandlerData\PluginInfoX is not. This may seem like a bug, but it prevents loading hacked plugins. MediaPlatform should be initialized before calling these methods. MediaPlatform can be compiled and created with different features, eg CreateMediaPlatformEx entrypoint and HX_FEATURE_FILEPREFS preprocessor definition. Preferences can be overriden by the application, so we need the application to setup MediaPlatform before calling any of these three functions. I've added checks and comments describing expected state. I've reworked the interface and implementation to enable removal of a preference at an arbitrary level of the preference hierarchy, allowing an application to remove only the preferences or mount points that it cares about. I've put the code that removes all preferences into its own function so that the parent-child preference iteration would be more readable. This duplicates a small amount of code. Questions or comments? Thanks, Tad Yeager At 08:55 AM 2/25/2009, Greg Wright wrote: >Does the media platform need to be 'restarted' after prefs are deleted, or >perhaps re-initialized? We should make sure we define what state the platform >and engine are in after such a function is called as it can be called at >any time. Perhaps just not allowing the call after some point, not sure. > >Personally, I really don't like adding numbers to interfaces as we >have done historically. Sometimes there isn't a better choice, but >in this case I think it might be better named with something that >referes to the platforms persistent data. Then you could clone the >other calls like Purge() and Reset() into this new interface. Perhaps >calls for the PluginPath stuff as well. Might be useful to have an >interface you could pass around that does that kind of stuff but >doesn't have Close(), Init() or other types of calls. > >--greg. > > > > > > >Tad Yeager wrote: >>Resending because a portion of a reply wasn't transmitted and there has >>been only one response. >>Synopsis: encapsulate the removal of persistent plugin data in the >>MediaPlatform. >>Summary: >>Applications and browser plugins attempt to kill registry keys prior to >>loading MediaPlatform/ObjectBroker so that plugin handler data will be >>regenerated when mount points are added. This happens at installation >>time or if an application detects that plugins have changed locations. >>The attached changes to MediaPlatform expose a method that deletes >>preferences using code factored out of MediaPlatform's Reset() >>function. The location and format of the persistent plugin data can >>change. The attached changes move ownership from MediaPlatform's clients >>to MediaPlatform. >>Branchs: >>head, hxclient_3_1_0_atlas >>Affected: MediaPlatform. >>Risks: low. _______________________________________________ Helix-client-dev mailing list [email protected] http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev
medpltfm.txt
(text/plain, 16.3 KB)
? Makefile
? client_medpltfm.sln
? client_medpltfm.vcproj
? client_medpltfm_hxmedpltfmdll.sln
? client_medpltfm_hxmedpltfmdll.vcproj
? client_medpltfm_hxmedpltfmlib.sln
? client_medpltfm_hxmedpltfmlib.vcproj
? dbg32
? debug
? pylinktmp-hxmedpltfm
? ribosome_logs
? test
? text
Index: chxmedpltfm.cpp
===================================================================
RCS file: /cvsroot/client/medpltfm/chxmedpltfm.cpp,v
retrieving revision 1.51.2.19
diff -u -2 -0 -r1.51.2.19 chxmedpltfm.cpp
--- chxmedpltfm.cpp 8 Nov 2008 17:25:36 -0000 1.51.2.19
+++ chxmedpltfm.cpp 4 Mar 2009 02:30:41 -0000
@@ -55,72 +55,76 @@
#include "hxwintyp.h"
#include "hxwin.h"
#include "chxmedpltfm.h"
#include "chxmedpltfmex.h"
#include "chxmedpltfmsched.h"
#include "hxoptsc.h"
#include "hxobjbrokrids.h"
#include "chxpckts.h"
#include "pckunpck.h"
#include "hxpref.h"
#include "hxtbuf.h"
#include "hxmutex.h"
#include "timebuff.h"
#include "hxcore.h"
#include "hxvalues.h"
#include "hxrquest.h"
#include "hxfiles.h"
#include "hxlistp.h"
+#include "hxstack.h"
+#include "hxstring.h"
+#include "hxpreferencesutils.h"
#include "dllaccesserver.h"
#include "cachobj.h"
#include "chxfgbuf.h"
#include "hxfsmgr.h"
#include "hxgrpen2.h"
#include "threngin.h"
#include "hxclreg.h"
#include "hxvsurf.h"
#include "hxsite2.h"
#include "hxmisus.h"
#include "cpacemkr.h"
#include "chxthread.h"
#include "hxpreferences.h"
#include "recognizer.h"
#include "hxxml.h"
#include "hxxmlprs.h"
#ifdef HELIX_FEATURE_HTTP_SERVICE
#include "chxhttp.h"
#include "hxhttp.h"
#endif
#include "hxinfcod.h"
#include "hxver.h"
#include "hxstrutl.h"
#include "dbcs.h"
#include "thrdutil.h"
#include "hxtlogutil.h"
//------------------------------- CHXMediaPlatform
BEGIN_INTERFACE_LIST( CHXMediaPlatform )
INTERFACE_LIST_ENTRY_SIMPLE( IHXMediaPlatform )
+ INTERFACE_LIST_ENTRY_SIMPLE( IHXMediaPlatformCleaner )
INTERFACE_LIST_ENTRY_SIMPLE( IHXCommonClassFactory )
INTERFACE_LIST_ENTRY_SIMPLE( IHXObjectManagerPrivate )
INTERFACE_LIST_ENTRY_DELEGATE_BLIND( _InternalQI )
END_INTERFACE_LIST
CHXMediaPlatform* CHXMediaPlatform::CreateInstance(CHXMediaPlatform* pParent,
CHXMediaPlatform* pRoot)
{
#ifdef HELIX_FEATURE_EXTENDED_MEDIAPLATFORM
return new CHXMediaPlatformEx((CHXMediaPlatformEx*)pParent, (CHXMediaPlatformEx*)pRoot);
#else // HELIX_FEATURE_EXTENDED_MEDIAPLATFORM
return new CHXMediaPlatform(pParent, pRoot);
#endif // HELIX_FEATURE_EXTENDED_MEDIAPLATFORM
}
CHXMediaPlatform::CHXMediaPlatform(CHXMediaPlatform* pParent, CHXMediaPlatform* pRoot)
:m_bInitialized(FALSE)
,m_lastError(HXR_OK)
@@ -586,44 +590,40 @@
}
// Extended context must be released last as it may have overriden
// services used by pther platform objects and it may also have
// aggregated itself into the platform.
// In such case, releasing of the external context will result in its
// destruction and thus any objects that may use its service must
// be released/closed first.
HX_RELEASE(m_pExtCCF);
HX_RELEASE(m_pExtContext);
m_bInitialized = FALSE;
return HXR_OK;
}
STDMETHODIMP
CHXMediaPlatform::Reset(IUnknown* pContext, HXBOOL bPlatformOnly)
{
HX_RESULT rc = HXR_OK;
- IHXBuffer* pPrefKey = NULL;
- IHXPreferences2* pPref2 = NULL;
- IHXPreferences3* pPref3 = NULL;
- IHXPreferenceEnumerator* pPrefEnumerator = NULL;
IHXPluginEnumerator* pPluginEnumerator = NULL;
if (!bPlatformOnly && m_pPluginHandlerUnkown)
{
if (HXR_OK == m_pPluginHandlerUnkown->QueryInterface(IID_IHXPluginEnumerator,
(void**)&pPluginEnumerator))
{
UINT32 ulIndex = 0;
UINT32 ulNumOfPlugins = pPluginEnumerator->GetNumOfPlugins();
IUnknown* pPlugin = NULL;
IHXPlugin2* pPlugin2 = NULL;
for(ulIndex = 0; ulIndex < ulNumOfPlugins; ulIndex++)
{
if (SUCCEEDED(pPluginEnumerator->GetPlugin(ulIndex, pPlugin)))
{
if (SUCCEEDED(pPlugin->QueryInterface(IID_IHXPlugin2, (void**)&pPlugin2)))
{
pPlugin2->Reset();
}
@@ -632,58 +632,217 @@
HX_RELEASE(pPlugin);
}
}
HX_RELEASE(pPluginEnumerator);
}
// We reset the m_pPreferences if it's already initialized via Init()
//
// On the other hand, Reset() can be called without Init(), this can
// happen when the app simply wants to reset the media platform
// during its un-installation
if (!m_pPreferences)
{
if (!m_pExtContext ||
HXR_OK != m_pExtContext->QueryInterface(IID_IHXPreferences, (void**)&m_pPreferences))
{
InitDefaultPreferences();
}
}
- // remove all the entries within m_pPreferences
- if (m_pPreferences &&
- HXR_OK == m_pPreferences->QueryInterface(IID_IHXPreferences2, (void**)&pPref2) &&
+ RemoveAllPreferences();
+
+ Close();
+
+ return HXR_OK;
+}
+
+void FlushPreferences(IHXPreferences* pPreferences)
+{
+#if defined(HELIX_FEATURE_FILEPREFS)
+ SPIHXPreferencesFile spFilePrefs = pPreferences;
+ if (spFilePrefs)
+ {
+ spFilePrefs->Flush();
+ }
+#endif // HELIX_FEATURE_FILEPREFS
+}
+
+STDMETHODIMP
+CHXMediaPlatform::RemoveAllPreferences(void)
+{
+ // Unlike Reset, we want the application to initialize preferences before
+ // calling this function because preferences can be overridden by applications.
+ if (!m_bInitialized || !m_pPreferences)
+ {
+ return HXR_NOT_INITIALIZED;
+ }
+
+ IHXBuffer* pPrefKey = NULL;
+ IHXPreferences2* pPref2 = NULL;
+ IHXPreferences3* pPref3 = NULL;
+ IHXPreferenceEnumerator* pPrefEnumerator = NULL;
+ // Preferences must be initalized or we do nothing
+ if (HXR_OK == m_pPreferences->QueryInterface(IID_IHXPreferences2, (void**)&pPref2) &&
HXR_OK == m_pPreferences->QueryInterface(IID_IHXPreferences3, (void**)&pPref3) &&
HXR_OK == pPref2->GetPreferenceEnumerator(pPrefEnumerator))
{
while (HXR_OK == pPrefEnumerator->GetPrefKey(0, pPrefKey))
{
pPref3->DeletePref((const char*)pPrefKey->GetBuffer());
+ }
+ }
+
+ FlushPreferences(m_pPreferences);
+ return HXR_OK;
+}
+
+STDMETHODIMP
+CHXMediaPlatform::RemovePersistentPluginData(void)
+{
+ return RemovePreferences("MountPoints");
+}
+
+STDMETHODIMP
+CHXMediaPlatform::RemoveNamedPreference(const char* pszPreferenceRootName)
+{
+ return RemovePreferences(pszPreferenceRootName);
+}
+
+HX_RESULT
+CHXMediaPlatform::RemovePreferences(const char* pszPreferenceRootName)
+{
+ // Unlike Reset, we want the application to initialize preferences before
+ // calling this function because preferences can be overridden by applications.
+ if (!m_bInitialized || !m_pPreferences)
+ {
+ return HXR_NOT_INITIALIZED;
+ }
+ HX_RESULT hr = RemovePreferences(m_pPreferences, pszPreferenceRootName);
+
+ FlushPreferences(m_pPreferences);
+ return hr;
+}
+
+bool FoundPreferenceKey(IHXBuffer* pPrefKey, const char* pszPreferenceRootName, int nPreferenceLength)
+{
+return ((int)pPrefKey->GetSize() >= nPreferenceLength && // assume pPrefKey buffer may not be NULL terminated,
+// Buffer size can be greater than string size by an arbitrary amount, so this check doesn't tell us what we want to know:
+// (int)pPrefKey->GetSize() <= nPreferenceLength && // but don't allow "MountPoints" to match "MountPointsWithSomeExtraStuff"
+ !strncmp(pszPreferenceRootName, (const char*)pPrefKey->GetBuffer(), nPreferenceLength)) ?
+ true :
+ false;
+}
+
+void PushPreferenceName(CHXString* strCurrentPrefKey, IHXBuffer* pPrefKey)
+{
+ if (!strCurrentPrefKey->IsEmpty())
+ {
+ (*strCurrentPrefKey) += HXPreferencesUtils::czPrefKeySeparator;
+ }
+ (*strCurrentPrefKey) += (const char*)pPrefKey->GetBuffer();
+}
+
+void PopPreferenceName(CHXString* strCurrentPrefKey)
+{
+ INT32 nLastOccurence = strCurrentPrefKey->ReverseFind(HXPreferencesUtils::czPrefKeySeparator);
+ *strCurrentPrefKey = (nLastOccurence >= 0) ? strCurrentPrefKey->Left(nLastOccurence) : CHXString("");
+}
+
+HX_RESULT
+CHXMediaPlatform::RemovePreferences(IHXPreferences* pPreferences, const char* pszPreferenceRootName)
+{
+ // Preferences must be initalized or we do nothing
+ if (!m_bInitialized || !pPreferences)
+ {
+ return HXR_NOT_INITIALIZED;
+ }
+
+ CHXStack preferenceIndicies;
+ CHXString strCurrentPrefKey;
+ IHXBuffer* pPrefKey = NULL;
+ IHXPreferences2* pPref2 = NULL;
+ IHXPreferences3* pPref3 = NULL;
+ IHXPreferenceEnumerator* pPrefEnumerator = NULL;
+ int nPreferenceLength = 0;
+
+ // may be called with NULL preference root name, which means delete all preferences
+ if (pszPreferenceRootName)
+ {
+ nPreferenceLength = strlen(pszPreferenceRootName);
+ }
+
+ if (HXR_OK == pPreferences->QueryInterface(IID_IHXPreferences2, (void**)&pPref2) &&
+ HXR_OK == pPreferences->QueryInterface(IID_IHXPreferences3, (void**)&pPref3) &&
+ HXR_OK == pPref2->GetPreferenceEnumerator(pPrefEnumerator))
+ {
+ int i = 0;
+ bool bDone = (HXR_OK != pPrefEnumerator->GetPrefKey(i, pPrefKey));
+ while (!bDone)
+ {
+ // remove tree rooted at pszPreferenceRootName
+ if (FoundPreferenceKey(pPrefKey, pszPreferenceRootName, nPreferenceLength))
+ {
+ PushPreferenceName(&strCurrentPrefKey, pPrefKey);
+ pPref3->DeletePref(strCurrentPrefKey);
+ HX_RELEASE(pPrefKey);
+ // assuming only one preference name rooted as pszPreferenceRootName
+ // it's deleted, so we're done
+ break;
+ }
+ else // descend into sub preferences
+ {
+ // Point parent index to next preference before pushing onto stack
+ i++;
+ // Begin sub pref; this will always succeed because pPrefKey is valid if
+ // we're here. GetPrefKey(0, ...) will fail below if there are no sub preferences
+ pPrefEnumerator->BeginSubPref((const char*)pPrefKey->GetBuffer());
+ preferenceIndicies.Push((void*)i);
+ PushPreferenceName(&strCurrentPrefKey, pPrefKey);
+ i = 0;
+ }
+ // Even if we're looking at SubPrefs, we're done with this pref because it didn't match
HX_RELEASE(pPrefKey);
+
+ // Decide whether we need to pop subpref stack, continue or finish iteration
+ while (HXR_OK != pPrefEnumerator->GetPrefKey(i, pPrefKey))
+ {
+ // Enumerator is pointed past the last preference
+ if ((int)(void*)preferenceIndicies.TopOfStack() != 0)
+ {
+ // Pop the subpref stack and continue iterating
+ pPrefEnumerator->EndSubPref();
+ i = (int)(void*)preferenceIndicies.Pop();
+ PopPreferenceName(&strCurrentPrefKey);
+ }
+ else
+ {
+ // Stack is empty, GetPrefKey failed, so we're done
+ bDone = true;
+ break;
+ }
+ }
}
HX_RELEASE(pPrefEnumerator);
HX_RELEASE(pPref3);
HX_RELEASE(pPref2);
}
-
- Close();
-
return HXR_OK;
}
STDMETHODIMP
CHXMediaPlatform::Purge(void)
{
// Purge is not supported on child media platform context
if (m_pParent)
{
return m_pParent->Purge();
}
#if !defined(_STATICALLY_LINKED) && defined(HELIX_FEATURE_PLUGINHANDLER2)
if (m_pPluginHandlerUnkown)
{
// shortcut, UnloadDeadDLLs() needs to be part of the interface
((Plugin2Handler*)(IHXPlugin2Handler*)m_pPluginHandlerUnkown)->UnloadDeadDLLs();
}
return HXR_OK;
Index: pub/chxmedpltfm.h
===================================================================
RCS file: /cvsroot/client/medpltfm/pub/chxmedpltfm.h,v
retrieving revision 1.19.2.6
diff -u -2 -0 -r1.19.2.6 chxmedpltfm.h
--- pub/chxmedpltfm.h 6 Jun 2008 00:37:44 -0000 1.19.2.6
+++ pub/chxmedpltfm.h 4 Mar 2009 02:42:15 -0000
@@ -99,40 +99,41 @@
struct PluginPathInfo
{
char* pszName;
IHXBuffer* pPath;
PluginPathInfo()
{
pszName = NULL;
pPath = NULL;
};
~PluginPathInfo()
{
HX_VECTOR_DELETE(pszName);
HX_RELEASE(pPath);
};
};
class CHXMediaPlatform : public CUnknownIMP
, public IHXMediaPlatform
+ , public IHXMediaPlatformCleaner
, public IHXCommonClassFactory
, public IHXObjectManagerPrivate
{
// The IUnknown implementation declaration
DECLARE_UNKNOWN( CHXMediaPlatform )
protected:
typedef enum
{
HX_MP_COM_INSTRINSIC = 0,
HX_MP_COM_REGULAR
} HX_MP_COM_TYPE;
HXBOOL m_bInitialized;
HX_RESULT m_lastError;
IUnknown* m_pExtContext;
IUnknown* m_pPluginHandlerUnkown;
IHXCommonClassFactory* m_pExtCCF;
@@ -187,72 +188,84 @@
CHXSimpleList* m_pSingleLoadPlugins;
CHXSimpleList* m_pLoadAtStartupPlugins;
HX_RESULT InitBasicServices(void);
HX_RESULT LoadStartupPlugins(void);
void UnloadStartupPlugins(void);
HX_RESULT InitExtendableServices(void);
HX_RESULT CheckAndQueryInterface(HX_MP_COM_TYPE type, REFIID riid, void** ppvObj);
HX_RESULT CheckAndCreateInstance(HX_MP_COM_TYPE type, REFCLSID rclsid, void** ppUnknown);
virtual HX_RESULT CreateIntrinsicType(REFCLSID rclsid, REF(IUnknown*) pUnknown, IUnknown* pOuter);
virtual HX_RESULT CreateGeneralType(REFCLSID clsid, REF(IUnknown*) pObject, IUnknown* pUnkOuter, IUnknown* pContext);
HX_RESULT CreateInstanceFromPluginHandler(REFCLSID rclsid, void** ppUnknown, IUnknown *pUnkOuter, IUnknown* pContext);
HX_RESULT InitDefaultPreferences(void);
HX_RESULT InitLogging();
HX_RESULT _InternalQI(REFIID riid, void** ppvObj);
+ // RemovePreferences is implemented in terms of the second RemovePreferences
+ HX_RESULT RemovePreferences(const char* pszPreferenceRootName);
+ HX_RESULT RemovePreferences(IHXPreferences* pPrefs, const char* pszPreferenceRootName);
public:
static CHXMediaPlatform* CreateInstance(CHXMediaPlatform* pParent = NULL,
CHXMediaPlatform* pRoot = NULL);
CHXMediaPlatform(CHXMediaPlatform* pParent = NULL, CHXMediaPlatform* pRoot = NULL);
~CHXMediaPlatform(void);
/*
* IHXMediaPlatform methods
* see common/include/ihxmedpltfm.h for detail description
*/
STDMETHOD(GetVersion) (THIS_
UINT32* pVersion);
STDMETHOD(AddPluginPath) (THIS_
const char* pszName,
const char* pszPath);
STDMETHOD(Init) (THIS_
IUnknown* pContext);
STDMETHOD(Close) (THIS);
STDMETHOD(Reset) (THIS_
IUnknown* pContext,
HXBOOL bPlatformOnly = TRUE);
STDMETHOD(Purge) (THIS);
STDMETHOD(CreateChildContext) (THIS_
IHXMediaPlatform** ppChildContext);
/*
+ * IHXMediaPlatformCleaner methods
+ */
+ STDMETHOD(RemovePersistentPluginData) (THIS);
+
+ STDMETHOD(RemoveNamedPreference) (THIS_ const char* pszPreferenceRootName);
+
+ STDMETHOD(RemoveAllPreferences) (THIS);
+
+ /*
* IHXCommonClassFactory methods
*/
STDMETHOD(CreateInstance) (THIS_
REFCLSID rclsid,
void** ppUnknown);
STDMETHOD(CreateInstanceAggregatable) (THIS_
REFCLSID rclsid,
REF(IUnknown*) ppUnknown,
IUnknown* pUnkOuter);
// IHXObjectManagerPrivate methods
STDMETHOD(ObjectFromCLSIDPrivate) (THIS_ REFCLSID clsid,REF(IUnknown *)pObject,
IUnknown *pUnkOuter, IUnknown* pContext );
STDMETHOD( UnloadPluginPrivate )(THIS_ REFCLSID clsid);
};
#endif /* _CHXMEDPLTFM_H_ */