|
|
#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); } }
|