how to cancel autoplay in xp

类别:VC语言 点击:0 评论:0 推荐:

#include <windows.h>
#include <shobjidl.h>
#include <shlobj.h>
#include <assert.h>


bool CancelRemoveDriverAutoPlay( bool b );

static HRESULT _RegisterForIQueryCancelAutoplay(  DWORD* pdwRegisterROT);
static HRESULT _UnregisterForIQueryCancelAutoplay(DWORD dwRegisterROT);
static bool IsWindowsXPOrGreater();


bool CancelRemoveDriverAutoPlay( bool b )
{
 if( !IsWindowsXPOrGreater() )
 {
  return false;
 }
 static bool s_bAutoPlayCanceled = false;
 static DWORD s_dwRot=0;

 if( s_bAutoPlayCanceled == b )
 {
  return true;
 }

 if( 0 == s_dwRot )
 {
  if( b )
  {
   HRESULT hr = _RegisterForIQueryCancelAutoplay(&s_dwRot );
   if( SUCCEEDED(hr) )
   {
    s_bAutoPlayCanceled = true;
    return true;    
   }
   else
   {
    assert(0);
    return false;
   }
  }
  else
  {
   return true;
  }
 }
 else
 {
  if( b )
  {
   return true;
  }
  else
  {
   HRESULT hr = _UnregisterForIQueryCancelAutoplay( s_dwRot );
   if( SUCCEEDED(hr) )
   {
    s_dwRot = 0;
    s_bAutoPlayCanceled = false;
    return true;
   }
   else
   {
    assert(0);
    return false;
   }
  }
 } 
}

static bool IsWindowsXPOrGreater()
{
 OSVERSIONINFOEXA osvi = {0};

 osvi.dwOSVersionInfoSize = sizeof(osvi);

 if (!GetVersionExA((OSVERSIONINFOA*)&osvi))
 {
  // If it failed, it must be a down level platform
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  GetVersionExA((OSVERSIONINFOA*)&osvi);
 }

 return (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId &&
  ((osvi.dwMajorVersion > 5) ||
  (osvi.dwMajorVersion == 5 && (osvi.dwMinorVersion > 0 ||
  (osvi.dwMinorVersion == 0 && LOWORD(osvi.dwBuildNumber) > 2195)))));
}


class CQueryCancelAutoplay : public IQueryCancelAutoPlay
{
public:
 // IUnknown interface
 STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
 STDMETHODIMP_(ULONG) AddRef();
 STDMETHODIMP_(ULONG) Release();

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

public:
 CQueryCancelAutoplay() : m_cRef(1){}
 ~CQueryCancelAutoplay(){}
private:
 ULONG               m_cRef;
};


static HRESULT GetCancelAutoPlayMoniker(IMoniker** ppmoniker)
{
 // Create the moniker that we'll put in the ROT 
 return CreateClassMoniker(CLSID_QueryCancelAutoPlay, ppmoniker);
}

HRESULT _RegisterForIQueryCancelAutoplay( DWORD* pdwRegisterROT)
{
 IMoniker* pmoniker =NULL;

 HRESULT hr = GetCancelAutoPlayMoniker( &pmoniker);

 if (SUCCEEDED(hr))
 {
  IRunningObjectTable* prot = NULL;
  hr = GetRunningObjectTable(0, &prot);

  if (SUCCEEDED(hr))
  {
   CQueryCancelAutoplay* pQCA = new CQueryCancelAutoplay();
   if ( NULL != pQCA )
   {
     IUnknown* punk=NULL;

     hr = pQCA->QueryInterface(IID_IUnknown, (void**)&punk);

     if (SUCCEEDED(hr))
     {
      // Register...
      hr = prot->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE,
       punk, pmoniker, pdwRegisterROT);

      punk->Release();
     }
    pQCA->Release();    
   }
   else
   {
    hr = E_OUTOFMEMORY;
   }
   prot->Release();
  }
  pmoniker->Release();
 }
 return hr;
}

HRESULT _UnregisterForIQueryCancelAutoplay(DWORD dwRegisterROT)
{
 IRunningObjectTable *prot;
 if (SUCCEEDED(GetRunningObjectTable(0, &prot)))
 {
  // Remove our instance from the ROT
  prot->Revoke(dwRegisterROT);
  prot->Release();
 }
 return S_OK;
}


STDMETHODIMP CQueryCancelAutoplay::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) CQueryCancelAutoplay::AddRef()
{
 return ::InterlockedIncrement((LONG*)&m_cRef);
}

STDMETHODIMP_(ULONG) CQueryCancelAutoplay::Release()
{
 ULONG cRef = ::InterlockedDecrement((LONG*)&m_cRef);

 if (!cRef)
 {
  delete this;
 }

 return cRef;
}

STDMETHODIMP CQueryCancelAutoplay::AllowAutoPlay(LPCWSTR pszPath,
             DWORD dwContentType, LPCWSTR pszLabel, DWORD dwSerialNumber)
{
 HRESULT hr = S_OK;
 //do what you want to do
 //return S_FALSE to cancel the autoplay
 //return S_OK to do autoplay
 return hr;
}

本文地址:http://com.8s8s.com/it/it160.htm