305 lines
8.5 KiB
C++
305 lines
8.5 KiB
C++
|
#include "setenum.h"
|
||
|
|
||
|
#include "dtctreg.h"
|
||
|
#include "cmmn.h"
|
||
|
|
||
|
#include "misc.h"
|
||
|
#include "reg.h"
|
||
|
#include "sfstr.h"
|
||
|
|
||
|
#include "tfids.h"
|
||
|
#include "dbg.h"
|
||
|
|
||
|
#define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
|
||
|
|
||
|
STDMETHODIMP CEnumAutoplayHandlerImpl::Next(LPWSTR* ppszHandler,
|
||
|
LPWSTR* ppszAction, LPWSTR* ppszProvider, LPWSTR* ppszIconLocation)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
*ppszHandler = NULL;
|
||
|
*ppszAction = NULL;
|
||
|
*ppszProvider = NULL;
|
||
|
*ppszIconLocation = NULL;
|
||
|
|
||
|
if (!_fTakeNoActionDone)
|
||
|
{
|
||
|
LPCWSTR pszHandler = TEXT("MSTakeNoAction");
|
||
|
WCHAR szAction[MAX_ACTION];
|
||
|
WCHAR szProvider[MAX_PROVIDER];
|
||
|
WCHAR szIconLocation[MAX_ICONLOCATION];
|
||
|
|
||
|
if (_rghkiHandlers)
|
||
|
{
|
||
|
if (_dwIndex < _cHandlers)
|
||
|
{
|
||
|
pszHandler = _rghkiHandlers[_dwIndex].szHandler;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_fTakeNoActionDone = TRUE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_fTakeNoActionDone = TRUE;
|
||
|
}
|
||
|
|
||
|
hr = _GetActionFromHandler(pszHandler, szAction, ARRAYSIZE(szAction));
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = _GetIconLocationFromHandler(pszHandler, szIconLocation,
|
||
|
ARRAYSIZE(szIconLocation));
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = _GetProviderFromHandler(pszHandler, szProvider,
|
||
|
ARRAYSIZE(szProvider));
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = _CoTaskMemCopy(pszHandler, ppszHandler);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = _CoTaskMemCopy(szAction,
|
||
|
ppszAction);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = _CoTaskMemCopy(szIconLocation,
|
||
|
ppszIconLocation);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = _CoTaskMemCopy(szProvider,
|
||
|
ppszProvider);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
if (*ppszHandler)
|
||
|
{
|
||
|
CoTaskMemFree((PVOID)*ppszHandler);
|
||
|
*ppszHandler = NULL;
|
||
|
}
|
||
|
if (*ppszAction)
|
||
|
{
|
||
|
CoTaskMemFree((PVOID)*ppszAction);
|
||
|
*ppszAction = NULL;
|
||
|
}
|
||
|
if (*ppszProvider)
|
||
|
{
|
||
|
CoTaskMemFree((PVOID)*ppszProvider);
|
||
|
*ppszProvider = NULL;
|
||
|
}
|
||
|
if (*ppszIconLocation)
|
||
|
{
|
||
|
CoTaskMemFree((PVOID)*ppszIconLocation);
|
||
|
*ppszIconLocation = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = S_FALSE;
|
||
|
}
|
||
|
|
||
|
++_dwIndex;
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT _GetKeyLastWriteTime(LPCWSTR pszHandler, FILETIME* pft)
|
||
|
{
|
||
|
WCHAR szKeyName[MAX_KEY] = SHDEVICEEVENTROOT(TEXT("Handlers\\"));
|
||
|
|
||
|
HRESULT hr = SafeStrCatN(szKeyName, pszHandler, ARRAYSIZE(szKeyName));
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
HKEY hkey;
|
||
|
|
||
|
hr = _RegOpenKey(HKEY_LOCAL_MACHINE, szKeyName, &hkey);
|
||
|
|
||
|
if (SUCCEEDED(hr) && (S_FALSE != hr))
|
||
|
{
|
||
|
if (ERROR_SUCCESS != RegQueryInfoKey(hkey,
|
||
|
NULL, // class buffer
|
||
|
0, // size of class buffer
|
||
|
NULL, // reserved
|
||
|
NULL, // number of subkeys
|
||
|
NULL, // longest subkey name
|
||
|
NULL, // longest class string
|
||
|
NULL, // number of value entries
|
||
|
NULL, // longest value name
|
||
|
NULL, // longest value data
|
||
|
NULL, // descriptor length
|
||
|
pft // last write time
|
||
|
))
|
||
|
{
|
||
|
// Bad. Set it to right now
|
||
|
GetSystemTimeAsFileTime(pft);
|
||
|
}
|
||
|
|
||
|
hr = S_OK;
|
||
|
|
||
|
_RegCloseKey(hkey);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CEnumAutoplayHandlerImpl::_Init(LPWSTR pszEventHandler)
|
||
|
{
|
||
|
WCHAR szKeyName[MAX_KEY] = SHDEVICEEVENTROOT(TEXT("EventHandlers\\"));
|
||
|
HRESULT hr = SafeStrCatN(szKeyName, pszEventHandler,
|
||
|
ARRAYSIZE(szKeyName));
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
HKEY hkey;
|
||
|
|
||
|
hr = _RegOpenKey(HKEY_LOCAL_MACHINE, szKeyName, &hkey);
|
||
|
|
||
|
if (SUCCEEDED(hr) && (S_FALSE != hr))
|
||
|
{
|
||
|
if (ERROR_SUCCESS == RegQueryInfoKey(hkey,
|
||
|
NULL, // class buffer
|
||
|
0, // size of class buffer
|
||
|
NULL, // reserved
|
||
|
NULL, // number of subkeys
|
||
|
NULL, // longest subkey name
|
||
|
NULL, // longest class string
|
||
|
&_cHandlers, // number of value entries
|
||
|
NULL, // longest value name
|
||
|
NULL, // longest value data
|
||
|
NULL, // descriptor length
|
||
|
NULL // last write time
|
||
|
))
|
||
|
{
|
||
|
hr = _AllocMemoryChunk<_HANDLERKEYINFO*>(_cHandlers *
|
||
|
sizeof(_HANDLERKEYINFO), &_rghkiHandlers);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
for (DWORD dw = 0; SUCCEEDED(hr) && (dw < _cHandlers); ++dw)
|
||
|
{
|
||
|
hr = _RegEnumStringValue(hkey, dw, _rghkiHandlers[dw].szHandler,
|
||
|
ARRAYSIZE(_rghkiHandlers[dw].szHandler));
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (S_FALSE != hr)
|
||
|
{
|
||
|
hr = _GetKeyLastWriteTime(
|
||
|
_rghkiHandlers[dw].szHandler,
|
||
|
&(_rghkiHandlers[dw].ftLastWriteTime));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// There's less then there was when we queried for it...
|
||
|
_cHandlers = dw;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// We don't care if this fails
|
||
|
_SortHandlers();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_FreeMemoryChunk<_HANDLERKEYINFO*>(_rghkiHandlers);
|
||
|
_rghkiHandlers = NULL;
|
||
|
_cHandlers = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_cHandlers = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = S_FALSE;
|
||
|
}
|
||
|
|
||
|
_RegCloseKey(hkey);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CEnumAutoplayHandlerImpl::_SwapHandlerKeyInfo(DWORD dwLeft,
|
||
|
DWORD dwRight)
|
||
|
{
|
||
|
_HANDLERKEYINFO hkiTmp = _rghkiHandlers[dwLeft];
|
||
|
|
||
|
_rghkiHandlers[dwLeft] = _rghkiHandlers[dwRight];
|
||
|
_rghkiHandlers[dwRight] = hkiTmp;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CEnumAutoplayHandlerImpl::_SortHandlers()
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
if (_rghkiHandlers)
|
||
|
{
|
||
|
hr = S_OK;
|
||
|
|
||
|
for (DWORD dwOuter = 0; dwOuter < _cHandlers; ++dwOuter)
|
||
|
{
|
||
|
_HANDLERKEYINFO* phkiOuter = &(_rghkiHandlers[dwOuter]);
|
||
|
ULARGE_INTEGER ulOuter;
|
||
|
ulOuter.LowPart = phkiOuter->ftLastWriteTime.dwLowDateTime;
|
||
|
ulOuter.HighPart = phkiOuter->ftLastWriteTime.dwHighDateTime;
|
||
|
|
||
|
for (DWORD dwInner = dwOuter + 1; dwInner < _cHandlers; ++dwInner)
|
||
|
{
|
||
|
_HANDLERKEYINFO* phkiInner = &(_rghkiHandlers[dwInner]);
|
||
|
|
||
|
ULARGE_INTEGER ulInner;
|
||
|
ulInner.LowPart = phkiInner->ftLastWriteTime.dwLowDateTime;
|
||
|
ulInner.HighPart = phkiInner->ftLastWriteTime.dwHighDateTime;
|
||
|
|
||
|
if (ulOuter.QuadPart > ulInner.QuadPart)
|
||
|
{
|
||
|
hr = _SwapHandlerKeyInfo(dwOuter, dwInner);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = S_FALSE;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
CEnumAutoplayHandlerImpl::CEnumAutoplayHandlerImpl() : _dwIndex(0), _rghkiHandlers(NULL),
|
||
|
_cHandlers(0), _fTakeNoActionDone(FALSE)
|
||
|
{}
|
||
|
|
||
|
CEnumAutoplayHandlerImpl::~CEnumAutoplayHandlerImpl()
|
||
|
{
|
||
|
if (_rghkiHandlers)
|
||
|
{
|
||
|
_FreeMemoryChunk<_HANDLERKEYINFO*>(_rghkiHandlers);
|
||
|
}
|
||
|
}
|