Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Stopping DVD/Audio CD autoplay

157 views
Skip to first unread message

Simon Macneall

unread,
May 5, 2004, 8:03:16 PM5/5/04
to
Hi all,

Has anyone had any success using the IQueryCancelAutoPlay interface to stop
Video DVD or Audio CD from auto playing on insertion? I've implemented the
AllowAutoPlay method, but it is not being called on disc insertion.

Thanks
Simon

Remy Lebeau (TeamB)

unread,
May 5, 2004, 8:14:03 PM5/5/04
to

"Simon Macneall" <macneall-at-iinet.net.au> wrote in message
news:Xns94E15253CC42Fm...@207.105.83.66...

IQueryCancelAutoPlay is only available under XP. Are you running XP at the
time? If so, then did you instantiate an instance of your
IQueryCancelAutoPlay descendant interface and register it with the OS's
Running Object Table at runtime? Did you also register your
IQueryCancelAutoPlay interface's CLSID in the Registry?


Gambit


Simon Macneall

unread,
May 5, 2004, 9:24:55 PM5/5/04
to
"Remy Lebeau \(TeamB\)" <gambit47...@no.spam.yahoo.com> wrote in
news:409984a1$1...@newsgroups.borland.com:

>
> IQueryCancelAutoPlay is only available under XP. Are you running XP
> at the time? If so, then did you instantiate an instance of your
> IQueryCancelAutoPlay descendant interface and register it with the
> OS's Running Object Table at runtime? Did you also register your
> IQueryCancelAutoPlay interface's CLSID in the Registry?
>
>
> Gambit
>

Yes, tested on XP, added to the ROT (have checked width rot viewer, and it
is there

I have put my CLSID in the registry

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer
\AutoplayHandlers\CancelAutoplay\CLSID, in a string value "0914A446-E6FA-
42a4-9A8A-7D9BDD87F017" with no data


here is my code, can you see anything wrong here? The only thing I am a bit
unsure of is that Borland (BCB6) had problems linking with
IID_IQueryCancelAutoPlay, so I had to add it manually


struct __declspec(
uuid("{DDEFE873-6997-4e68-BE26-39B633ADBE12}")) IID_IQueryCancelAutoPlay;

DEFINE_GUID(IID_IQueryCancelAutoPlay,
0xDDEFE873, 0x6997, 0x4e68, 0xBE, 0x26, 0x39, 0xB6, 0x33, 0xAD, 0xBE,
0x12);

class CAutoPlayInterceptor : public CUnknown, public IQueryCancelAutoPlay
{
protected:
public:
DECLARE_IUNKNOWN
CAutoPlayInterceptor();
~CAutoPlayInterceptor();
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);
STDMETHODIMP AllowAutoPlay(LPCWSTR pszPath, DWORD dwContentType, LPCWSTR
pszLabel, DWORD dwSerialNumber);
};

CAutoPlayInterceptor::CAutoPlayInterceptor() :
CUnknown("Auto Play Interceptor", NULL)
{
}

CAutoPlayInterceptor::~CAutoPlayInterceptor()
{
}

STDMETHODIMP CAutoPlayInterceptor::AllowAutoPlay(LPCWSTR pszPath, DWORD
dwContentType, LPCWSTR pszLabel, DWORD dwSerialNumber)
{
if (dwContentType == ARCONTENT_DVDMOVIE || dwContentType ==
ARCONTENT_AUTOPLAYVIDEO)
{
OutputDebugString("Killing autoplay");
return S_FALSE;
}
OutputDebugString("Got AllowAutoPlay, allowing it");
return S_OK;
}

STDMETHODIMP CAutoPlayInterceptor::NonDelegatingQueryInterface(REFIID riid,
void** ppv)
{
if (riid == IID_IQueryCancelAutoPlay)
{
return GetInterface(( IQueryCancelAutoPlay*)this, ppv);
}
else
{
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
}

Thanks
Simon

Remy Lebeau (TeamB)

unread,
May 5, 2004, 11:22:00 PM5/5/04
to

"Simon Macneall" <macneall-at-iinet.net.au> wrote in message
news:Xns94E160383D857m...@207.105.83.66...

> I have put my CLSID in the registry

Are you using a Type Library? Did you register the standard registration
values for COM interfaces in the Registry? Did you put your CLSID value
under the HKCR\CLSID key, with values to point back to your executable file?

> "0914A446-E6FA-42a4-9A8A-7D9BDD87F017"

Where is that value defined in your code?

> class CAutoPlayInterceptor : public CUnknown, public IQueryCancelAutoPlay

Are you using MFC?


Gambit


Jim Dodd

unread,
May 6, 2004, 8:51:27 AM5/6/04
to

Simon Macneall

unread,
May 6, 2004, 7:01:14 PM5/6/04
to
Jim Dodd <bcbuil...@yahoo.com> wrote in
news:409a...@newsgroups.borland.com:

> Does this note from MSDN help?
>
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellc
> c/platform/shell/programmersguide/shell_basics/shell_basics_extending/a
> utorun/autoplay_reg.asp
>
> Regards,
>
> Jim Dodd
> Onset Computer Corp.
>
>

Thanks, but no, that message is only sent for discs that have an
autorun.inf file, which Audio CDs and Movie DVDs don't.

Simon

Simon Macneall

unread,
May 6, 2004, 7:42:45 PM5/6/04
to
"Remy Lebeau \(TeamB\)" <gambit47...@no.spam.yahoo.com> wrote in
news:4099b0ae$1...@newsgroups.borland.com:

>
> "Simon Macneall" <macneall-at-iinet.net.au> wrote in message
> news:Xns94E160383D857m...@207.105.83.66...
>
>> I have put my CLSID in the registry
>
> Are you using a Type Library? Did you register the standard
> registration values for COM interfaces in the Registry? Did you put
> your CLSID value under the HKCR\CLSID key, with values to point back
> to your executable file?
>

All I did was create a class that implements the interface and added it to
my executable. What standard COM interfaces need to be registered, and
where? No, are you supposed to also put your CLSID somewhere under HKCR?

>> "0914A446-E6FA-42a4-9A8A-7D9BDD87F017"
>
> Where is that value defined in your code?

in a .h file like thus

struct __declspec(
uuid("{0914A446-E6FA-42a4-9A8A-7D9BDD87F017}")) CLSID_AutoPlayInterceptor;

>
>> class CAutoPlayInterceptor : public CUnknown, public
>> IQueryCancelAutoPlay
>
> Are you using MFC?

This is a standard Borland VCL exe and I am getting the Interface stuff
from DirectShow

Thanks
Simon

Remy Lebeau (TeamB)

unread,
May 6, 2004, 8:15:03 PM5/6/04
to

"Simon Macneall" <macneall-at-iinet.net.au> wrote in message
news:Xns94E24E78DCBC3m...@207.105.83.66...

> All I did was create a class that implements the interface and added it to
> my executable.

Further reading of MSDN shows the following:

"Upon presentation of media, the Shell searches the ROT for a component
implementing IQueryCancelAutoPlay. If one is found, ***the class identifier
(CLSID) of that component's moniker*** is extracted."

This suggests that your IQueryCancelAutoPlay interface has to support the
IMoniker interface as well. IMoniker derives from IPersist, which has a
GetClassID() method for retreiving the object's CLSID. I will bet that your
interface does not support that properly, so when the OS goes looking for
your object, it can't verify the CLSID so your interface doesn't get called
to block the AutoRun. If you look in your QueryInterface(), does
IID_IMoniker (or similar) ever get requested?

I do notice that there is a SHCreateQueryCancelAutoPlayMoniker() function
available as well.

BTW, how are you adding your interface to the ROT in the first place?


Gambit


Simon Macneall

unread,
May 10, 2004, 7:16:52 PM5/10/04
to
"Remy Lebeau \(TeamB\)" <gambit47...@no.spam.yahoo.com> wrote in
news:409ad659$1...@newsgroups.borland.com:

> Further reading of MSDN shows the following:
>
> "Upon presentation of media, the Shell searches the ROT for a
> component
> implementing IQueryCancelAutoPlay. If one is found, ***the class
> identifier (CLSID) of that component's moniker*** is extracted."
>
> This suggests that your IQueryCancelAutoPlay interface has to support
> the IMoniker interface as well. IMoniker derives from IPersist, which
> has a GetClassID() method for retreiving the object's CLSID. I will
> bet that your interface does not support that properly, so when the OS
> goes looking for your object, it can't verify the CLSID so your
> interface doesn't get called to block the AutoRun. If you look in
> your QueryInterface(), does IID_IMoniker (or similar) ever get
> requested?
>
> I do notice that there is a SHCreateQueryCancelAutoPlayMoniker()
> function available as well.
>
> BTW, how are you adding your interface to the ROT in the first place?
>
>

Thanks for your help Remy, I got it working using a sample I found in the
November 2001 MSDN, and adding the registry key that we talked about
earlier.

As for adding to the ROT...

namespace
{
DWORD rotReg = 0xf000000;
}

DWORD DirectXUtils::AddGraphToROT(IUnknown* inGraph)
{
CComPtr<IMoniker> moniker;
CComPtr<IRunningObjectTable> rot;
DWORD retVal = 0;
if (SUCCEEDED(GetRunningObjectTable(0, &rot)))
{
WCHAR wsz[256];
wsprintfW(wsz, L"AutoPlayInterceptor %08x pid %08x", 0,
GetCurrentProcessId());
if (SUCCEEDED(CreateItemMoniker(L"!", wsz, &moniker)))
{
retVal = rotReg;
rot->Register(0, inGraph, moniker, &retVal);
rotReg = retVal ? rotReg + 1 : rotReg;
}
}
return retVal;
}

was what I had previously, which was adding to the ROT, I am now using
the code from the MSDN article...

Simon

Simon Macneall

unread,
May 10, 2004, 7:18:10 PM5/10/04
to
Simon Macneall <macneall-at-iinet.net.au> wrote in
news:Xns94E247CC3DCDBm...@207.105.83.66:

>
> Thanks, but no, that message is only sent for discs that have an
> autorun.inf file, which Audio CDs and Movie DVDs don't.
>
> Simon
>

Just to update, apparently that message is supposed to be sent on insertion
of all discs. It is working on the XP laptop that we have here, but not on
my 2k development machine. If anyone knows why I would be grateful for the
information.

Simon

Remy Lebeau (TeamB)

unread,
May 10, 2004, 8:23:51 PM5/10/04
to

"Simon Macneall" <macneall-at-iinet.net.au> wrote in message
news:Xns94E64A765FD08m...@207.105.83.66...

> Thanks for your help Remy, I got it working using a sample I found in the
> November 2001 MSDN, and adding the registry key that we talked about
> earlier.

Can you please show your actual code?


Gambit


Remy Lebeau (TeamB)

unread,
May 10, 2004, 8:18:48 PM5/10/04
to

"Simon Macneall" <macneall-at-iinet.net.au> wrote in message
news:Xns94E64A765FD08m...@207.105.83.66...

> WCHAR wsz[256];
> wsprintfW(wsz, L"AutoPlayInterceptor %08x pid %08x", 0,
> GetCurrentProcessId());
> if (SUCCEEDED(CreateItemMoniker(L"!", wsz, &moniker)))

I suspect that you should be using SHCreateQueryCancelAutoPlayMoniker()
instead of CreateItemMoniker().

> rot->Register(0, inGraph, moniker, &retVal);

You are registering an IMoniker that has no actual connection to your custom
IQueryCancelAutoPlay object at all. I don't see how the ROT can query the
OS-provided IMoniker to gain information about your IQueryCancelAutoPlay
object when it needs it.


Gambit


Simon Macneall

unread,
May 10, 2004, 8:37:24 PM5/10/04
to
"Remy Lebeau \(TeamB\)" <gambit47...@no.spam.yahoo.com> wrote in
news:40a01e60$1...@newsgroups.borland.com:

>
> Can you please show your actual code?
>
>
> Gambit
>
>
>

Sure, this is all taken from
<http://msdn.microsoft.com/msdnmag/issues/01/11/autoplay/default.aspx>

Enjoy,
Simon

AutoPlayInterceptor.h

#ifndef AUTO_PLAY_INTERCEPTOR_H
#define AUTO_PLAY_INTERCEPTOR_H

#include <thirdparty/DirectXBaseClasses.h>
#include "shobjidl.h"
#include <initguid.h>

class CAutoPlayInterceptor : public IQueryCancelAutoPlay
{
protected:
public:
STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();

STDMETHODIMP AllowAutoPlay(LPCWSTR pszPath, DWORD dwContentType, LPCWSTR
pszLabel, DWORD dwSerialNumber);

HRESULT Init(DWORD dwContentType);
CAutoPlayInterceptor();
~CAutoPlayInterceptor(){};

private:
ULONG _cRef;
DWORD _dwContentType;
};

#endif // AUTO_PLAY_INTERCEPTOR_H

AutoPlayInterceptoruids.h

const static CLSID g_clsidAutoPlayInterceptor =
{ 0x0914a446, 0xe6fa, 0x42a4,
{ 0x9a, 0x8a, 0x7d, 0x9b, 0xdd, 0x87, 0xf0, 0x17 }};

struct __declspec(
uuid("{0914A446-E6FA-42a4-9A8A-7D9BDD87F017}")) CLSID_AutoPlayInterceptor;

DEFINE_GUID(CLSID_AutoPlayInterceptor,
0x0914A446, 0xE6FA, 0x42a4, 0x9A, 0x8A, 0x7D, 0x9B, 0xDD, 0x87, 0xF0,
0x17);

struct __declspec(
uuid("{DDEFE873-6997-4e68-BE26-39B633ADBE12}")) CLSID_QueryCancelAutoPlay;

DEFINE_GUID(CLSID_QueryCancelAutoPlay,


0xDDEFE873, 0x6997, 0x4e68, 0xBE, 0x26, 0x39, 0xB6, 0x33, 0xAD, 0xBE,
0x12);

struct __declspec(
uuid("{DDEFE873-6997-4e68-BE26-39B633ADBE12}")) IID_IQueryCancelAutoPlay;

DEFINE_GUID(IID_IQueryCancelAutoPlay,
0xDDEFE873, 0x6997, 0x4e68, 0xBE, 0x26, 0x39, 0xB6, 0x33, 0xAD, 0xBE,
0x12);


AutoPlayInterceptor.cpp

#include "AutoPlayInterceptor.h"
#include "AutoPlayIntercepteruids.h"

CAutoPlayInterceptor::CAutoPlayInterceptor() :
_cRef(1)
{
}

HRESULT CAutoPlayInterceptor::Init(DWORD dwContentType)
{
_dwContentType = dwContentType;
return S_OK;
}

STDMETHODIMP CAutoPlayInterceptor::AllowAutoPlay(LPCWSTR pszPath, DWORD
dwContentType, LPCWSTR pszLabel, DWORD dwSerialNumber)
{

HRESULT hr = S_OK;
if (dwContentType & _dwContentType)
{
hr = S_FALSE;
}
return hr;
}

STDMETHODIMP CAutoPlayInterceptor::QueryInterface(REFIID riid, void** ppv)
{
IUnknown* punk = NULL;
HRESULT hr = S_OK;
if (IID_IUnknown == riid)
{
punk = static_cast<IUnknown*>(this);
punk->AddRef();
}
else
{
if (IID_IQueryCancelAutoPlay == riid)
{
punk = static_cast<IQueryCancelAutoPlay*>(this);
punk->AddRef();
}
else
{
hr = E_NOINTERFACE;
}
}
*ppv = punk;
return hr;
}

STDMETHODIMP_(ULONG) CAutoPlayInterceptor::AddRef()
{
return ::InterlockedIncrement((LONG*)&_cRef);
}

STDMETHODIMP_(ULONG) CAutoPlayInterceptor::Release()
{
ULONG cRef = ::InterlockedDecrement((LONG*)&_cRef);
if (!cRef)
{
delete this;
}
return cRef;
}

Add


HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer

\AutoplayHandlers\CancelAutoplay\CLSID\0914A446-E6FA-42A4-9A8A-7D9BDD87F017
as a string key with no value


In the application, Call RegisterAutoPlay to activate, and
UnRegisterAutoplay to disable

void __fastcall TDVDForm::UnRegisterAutoplay()
{
IRunningObjectTable *prot;
if (SUCCEEDED(GetRunningObjectTable(0, &prot)))
{
prot->Revoke(_dwRegisterROT);
prot->Release();
}
}

void __fastcall TDVDForm::RegisterAutoplay()
{
DWORD dwContentType = ARCONTENT_DVDMOVIE;

IMoniker* pMoniker;
HRESULT hr = CreateClassMoniker(g_clsidAutoPlayInterceptor, &pMoniker);
if (SUCCEEDED(hr))
{
IRunningObjectTable* prot;
hr = GetRunningObjectTable(0, &prot);
if (SUCCEEDED(hr))
{
CAutoPlayInterceptor* pQCA = new CAutoPlayInterceptor();
if (pQCA)
{
hr = pQCA->Init(dwContentType);
if (SUCCEEDED(hr))
{
IUnknown* punk;
hr = pQCA->QueryInterface(IID_IUnknown, (void**)&punk);
if (SUCCEEDED(hr))
{
// register
hr = prot->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE,
punk, pMoniker, &_dwRegisterROT);
if (SUCCEEDED(hr))
{
dprintf("Registered!!!");
}
punk->Release();
}
}
pQCA->Release();
}
else
{
hr = E_OUTOFMEMORY;
}
prot->Release();
}
pMoniker->Release();
}
}

0 new messages