Commit 9df2a843 authored by Jean-Paul Saman's avatar Jean-Paul Saman

activex: Fix heap corrumption on Async event delivery

The heap corruption occured when events returned a value. Since the events cross COM boundaries,
the values returned should be allocated in COM context too. Allocating the memory with CoMemTaskAlloc()
should be used instead of new or malloc().
parent 88f536c0
...@@ -365,6 +365,7 @@ VLCConnectionPointContainer::~VLCConnectionPointContainer() ...@@ -365,6 +365,7 @@ VLCConnectionPointContainer::~VLCConnectionPointContainer()
{ {
EnterCriticalSection(&csEvents); EnterCriticalSection(&csEvents);
isRunning = FALSE; isRunning = FALSE;
freeze = TRUE;
ConditionSignal(&sEvents); ConditionSignal(&sEvents);
LeaveCriticalSection(&csEvents); LeaveCriticalSection(&csEvents);
...@@ -376,6 +377,11 @@ VLCConnectionPointContainer::~VLCConnectionPointContainer() ...@@ -376,6 +377,11 @@ VLCConnectionPointContainer::~VLCConnectionPointContainer()
ConditionDestroy(&sEvents); ConditionDestroy(&sEvents);
DeleteCriticalSection(&csEvents); DeleteCriticalSection(&csEvents);
_v_cps.clear();
while(!_q_events.empty()) {
_q_events.pop();
};
delete _p_props; delete _p_props;
delete _p_events; delete _p_events;
}; };
......
...@@ -297,6 +297,7 @@ STDAPI DllRegisterServer(VOID) ...@@ -297,6 +297,7 @@ STDAPI DllRegisterServer(VOID)
DWORD DllPathLen=GetModuleFileName(h_instance, DllPath, MAX_PATH) ; DWORD DllPathLen=GetModuleFileName(h_instance, DllPath, MAX_PATH) ;
if( 0 == DllPathLen ) if( 0 == DllPathLen )
return E_UNEXPECTED; return E_UNEXPECTED;
DllPath[MAX_PATH-1] = '\0';
HKEY hBaseKey; HKEY hBaseKey;
......
...@@ -214,6 +214,11 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) : ...@@ -214,6 +214,11 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) :
_i_codepage(CP_ACP), _i_codepage(CP_ACP),
_b_usermode(TRUE) _b_usermode(TRUE)
{ {
/*
** bump refcount to avoid recursive release from
** following interfaces when releasing this interface
*/
AddRef();
p_class->AddRef(); p_class->AddRef();
vlcOleControl = new VLCOleControl(this); vlcOleControl = new VLCOleControl(this);
...@@ -244,12 +249,6 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) : ...@@ -244,12 +249,6 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) :
VLCPlugin::~VLCPlugin() VLCPlugin::~VLCPlugin()
{ {
/*
** bump refcount to avoid recursive release from
** following interfaces when releasing this interface
*/
AddRef();
delete vlcSupportErrorInfo; delete vlcSupportErrorInfo;
delete vlcOleObject; delete vlcOleObject;
delete vlcDataObject; delete vlcDataObject;
...@@ -285,6 +284,7 @@ VLCPlugin::~VLCPlugin() ...@@ -285,6 +284,7 @@ VLCPlugin::~VLCPlugin()
if( _p_libvlc ) { libvlc_release(_p_libvlc); _p_libvlc=NULL; } if( _p_libvlc ) { libvlc_release(_p_libvlc); _p_libvlc=NULL; }
_p_class->Release(); _p_class->Release();
Release();
}; };
STDMETHODIMP VLCPlugin::QueryInterface(REFIID riid, void **ppv) STDMETHODIMP VLCPlugin::QueryInterface(REFIID riid, void **ppv)
...@@ -442,6 +442,7 @@ void VLCPlugin::initVLC() ...@@ -442,6 +442,7 @@ void VLCPlugin::initVLC()
{ {
TCHAR w_progpath[MAX_PATH]; TCHAR w_progpath[MAX_PATH];
DWORD len = GetModuleFileName(DllGetModule(), w_progpath, MAX_PATH); DWORD len = GetModuleFileName(DllGetModule(), w_progpath, MAX_PATH);
w_progpath[MAX_PATH-1] = '\0';
if( len > 0 ) if( len > 0 )
{ {
len = WideCharToMultiByte(CP_UTF8, 0, w_progpath, len, p_progpath, len = WideCharToMultiByte(CP_UTF8, 0, w_progpath, len, p_progpath,
...@@ -466,6 +467,7 @@ void VLCPlugin::initVLC() ...@@ -466,6 +467,7 @@ void VLCPlugin::initVLC()
if( RegQueryValueEx( h_key, TEXT("InstallDir"), 0, &i_type, if( RegQueryValueEx( h_key, TEXT("InstallDir"), 0, &i_type,
(LPBYTE)w_pluginpath, &i_data ) == ERROR_SUCCESS ) (LPBYTE)w_pluginpath, &i_data ) == ERROR_SUCCESS )
{ {
w_pluginpath[MAX_PATH-1] = '\0';
if( i_type == REG_SZ ) if( i_type == REG_SZ )
{ {
if( WideCharToMultiByte(CP_UTF8, 0, w_pluginpath, -1, p_pluginpath, if( WideCharToMultiByte(CP_UTF8, 0, w_pluginpath, -1, p_pluginpath,
...@@ -1107,10 +1109,14 @@ static void handle_input_state_event(const libvlc_event_t* event, void *param) ...@@ -1107,10 +1109,14 @@ static void handle_input_state_event(const libvlc_event_t* event, void *param)
void VLCPlugin::fireOnMediaPlayerTimeChangedEvent(long time) void VLCPlugin::fireOnMediaPlayerTimeChangedEvent(long time)
{ {
VARIANT varPos; DISPPARAMS params;
DISPPARAMS params = { &varPos, NULL, 1, 0 }; params.cArgs = 1;
varPos.vt = VT_I4; params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
varPos.lVal = time; memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
params.rgvarg[0].vt = VT_I4;
params.rgvarg[0].lVal = time;
params.rgdispidNamedArgs = NULL;
params.cNamedArgs = 0;
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerTimeChangedEvent, &params); vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerTimeChangedEvent, &params);
}; };
...@@ -1122,10 +1128,14 @@ static void handle_time_changed_event(const libvlc_event_t* event, void *param) ...@@ -1122,10 +1128,14 @@ static void handle_time_changed_event(const libvlc_event_t* event, void *param)
void VLCPlugin::fireOnMediaPlayerPositionChangedEvent(long position) void VLCPlugin::fireOnMediaPlayerPositionChangedEvent(long position)
{ {
VARIANT varPos; DISPPARAMS params;
DISPPARAMS params = { &varPos, NULL, 1, 0 }; params.cArgs = 1;
varPos.vt = VT_I4; params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
varPos.lVal = position; memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
params.rgvarg[0].vt = VT_I4;
params.rgvarg[0].lVal = position;
params.rgdispidNamedArgs = NULL;
params.cNamedArgs = 0;
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPositionChangedEvent, &params); vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPositionChangedEvent, &params);
}; };
...@@ -1138,10 +1148,14 @@ static void handle_position_changed_event(const libvlc_event_t* event, void *par ...@@ -1138,10 +1148,14 @@ static void handle_position_changed_event(const libvlc_event_t* event, void *par
#define B(val) ((val) ? 0xFFFF : 0x0000) #define B(val) ((val) ? 0xFFFF : 0x0000)
void VLCPlugin::fireOnMediaPlayerSeekableChangedEvent(VARIANT_BOOL seekable) void VLCPlugin::fireOnMediaPlayerSeekableChangedEvent(VARIANT_BOOL seekable)
{ {
VARIANT varSeek; DISPPARAMS params;
DISPPARAMS params = { &varSeek, NULL, 1, 0 }; params.cArgs = 1;
varSeek.vt = VT_BOOL; params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
varSeek.boolVal = seekable; memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
params.rgvarg[0].vt = VT_BOOL;
params.rgvarg[0].boolVal = seekable;
params.rgdispidNamedArgs = NULL;
params.cNamedArgs = 0;
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerSeekableChangedEvent, &params); vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerSeekableChangedEvent, &params);
}; };
...@@ -1153,10 +1167,14 @@ static void handle_seekable_changed_event(const libvlc_event_t* event, void *par ...@@ -1153,10 +1167,14 @@ static void handle_seekable_changed_event(const libvlc_event_t* event, void *par
void VLCPlugin::fireOnMediaPlayerPausableChangedEvent(VARIANT_BOOL pausable) void VLCPlugin::fireOnMediaPlayerPausableChangedEvent(VARIANT_BOOL pausable)
{ {
VARIANT varPause; DISPPARAMS params;
DISPPARAMS params = { &varPause, NULL, 1, 0 }; params.cArgs = 1;
varPause.vt = VT_BOOL; params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ;
varPause.boolVal = pausable; memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs);
params.rgvarg[0].vt = VT_BOOL;
params.rgvarg[0].boolVal = pausable;
params.rgdispidNamedArgs = NULL;
params.cNamedArgs = 0;
vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPausableChangedEvent, &params); vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPausableChangedEvent, &params);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment