|
|
#include "shellprv.h"
#include "ids.h"
#include "hwcmmn.h"
#include "apdlglog.h"
#include "mtptl.h"
BOOL _AreHandlersDifferent(LPCWSTR /*pszOriginal*/, LPCWSTR /*pszNew*/) { return TRUE; }
CHandlerDataArray::~CHandlerDataArray() { if (IsDPASet()) { DestroyCallback(_ReleaseHandler, NULL); } }
BOOL CHandlerDataArray::_IsDemotedHandler(PCWSTR pszHandler) { return ((0 == StrCmpIW(pszHandler, L"MSTakeNoAction")) || (0 == StrCmpIW(pszHandler, L"MSOpenFolder"))); } HRESULT CHandlerDataArray::AddHandler(CHandlerData *pdata) { // always insert ahead of TakeNoAction and OpenFolder
int iInsert; if (!_IsDemotedHandler(pdata->_pszHandler)) { int c = GetPtrCount(); for (iInsert = 0; iInsert < c; iInsert++) { if (_IsDemotedHandler(GetPtr(iInsert)->_pszHandler)) { // insert here
break; } } iInsert = InsertPtr(iInsert, pdata); } else { iInsert = AppendPtr(pdata); }
return DPA_ERR != iInsert ? S_OK : E_OUTOFMEMORY; }
BOOL CHandlerDataArray::IsDuplicateCommand(PCWSTR pszCommand) { WCHAR sz[MAX_PATH * 2]; BOOL fRet = FALSE; int c = GetPtrCount(); for (int i = 0; i < c; i++) { CHandlerData *pdata = GetPtr(i); if (SUCCEEDED(pdata->_GetCommand(sz, ARRAYSIZE(sz)))) { fRet = (0 == StrCmpIW(pszCommand, sz)); if (fRet) break; } } return fRet; }
// We are erring on the side of safety here by giving FALSE positives
// sometimes. This could be optimized to consider if we have diff handler
// just because one is missing.
void CContentTypeData::UpdateDirty() { BOOL fDirty = _AreHandlersDifferent(_pszHandlerDefault, _pszHandlerDefaultOriginal) || (HANDLERDEFAULT_DEFAULTSAREDIFFERENT & _dwHandlerDefaultFlags);
_SetDirty(fDirty); }
#define SOFTPREFIX TEXT("[soft]")
HRESULT CContentTypeData::CommitChangesToStorage() { HRESULT hr = S_OK;
if (_AreHandlersDifferent(_pszHandlerDefault, _pszHandlerDefaultOriginal) || (HANDLERDEFAULT_DEFAULTSAREDIFFERENT & _dwHandlerDefaultFlags)) { // Yep, changed
IAutoplayHandler* piah;
hr = _GetAutoplayHandler(_szDrive, TEXT("ContentArrival"), _szContentTypeHandler, &piah); if (SUCCEEDED(hr)) { if (!_fSoftCommit) { hr = piah->SetDefaultHandler(_pszHandlerDefault); } else { WCHAR szHandler[MAX_HANDLER + ARRAYSIZE(SOFTPREFIX)];
lstrcpyn(szHandler, SOFTPREFIX, ARRAYSIZE(szHandler)); StrCatBuff(szHandler, _pszHandlerDefault, ARRAYSIZE(szHandler));
hr = piah->SetDefaultHandler(szHandler); }
piah->Release(); } }
if (SUCCEEDED(hr)) { _SetHandlerDefault(&_pszHandlerDefaultOriginal, _pszHandlerDefault); }
return hr; }
CContentTypeData::~CContentTypeData() { if (_pszHandlerDefaultOriginal) { CoTaskMemFree(_pszHandlerDefaultOriginal); }
if (_pszHandlerDefault) { CoTaskMemFree(_pszHandlerDefault); } }
HRESULT _MakeActionString(LPCWSTR pszAction, LPWSTR* ppszAction2) { *ppszAction2 = NULL;
WCHAR szAction[250]; HRESULT hr = SHLoadIndirectString(pszAction, szAction, ARRAYSIZE(szAction), NULL); if (SUCCEEDED(hr)) { hr = SHStrDup(szAction, ppszAction2); }
return hr; }
HRESULT _MakeProviderString(LPCWSTR pszProvider, LPWSTR* ppszProvider2) { WCHAR szProviderNonMUI[250]; HRESULT hr = SHLoadIndirectString(pszProvider, szProviderNonMUI, ARRAYSIZE(szProviderNonMUI), NULL);
if (SUCCEEDED(hr)) { WCHAR szUsing[50];
if (LoadString(g_hinst, IDS_AP_USING, szUsing, ARRAYSIZE(szUsing))) { WCHAR szProvider2[250];
hr = StringCchPrintf(szProvider2, ARRAYSIZE(szProvider2), szUsing, szProviderNonMUI); if (SUCCEEDED(hr)) { hr = SHStrDup(szProvider2, ppszProvider2); } } else { hr = E_FAIL; } }
return hr; }
inline void _CoTaskMemFree(void* pv) { if (pv) { CoTaskMemFree(pv); } }
HRESULT _CreateHandlerData( PCWSTR pszAction, PCWSTR pszProvider, PWSTR *ppszHandler, // IN/OUT
PWSTR *ppszIcon, // IN/OUT
CHandlerData **ppdata) { *ppdata = 0; LPWSTR pszAction2 = NULL; HRESULT hr = _MakeActionString(pszAction, &pszAction2); if (SUCCEEDED(hr)) { LPWSTR pszProvider2 = NULL; // Special case this guy, we don't want to say:
// "Take no action, using Microsoft Windows"
if (lstrcmp(*ppszHandler, TEXT("MSTakeNoAction"))) { hr = _MakeProviderString(pszProvider, &pszProvider2); } // else this is NULL, and ignored
if (SUCCEEDED(hr)) { *ppdata = new CHandlerData(); if (*ppdata) { // give away ownership of these allocations
(*ppdata)->Init(*ppszHandler, pszAction2, *ppszIcon, pszProvider2);
*ppszHandler = NULL; *ppszIcon = NULL; pszAction2 = NULL; pszProvider2 = NULL; } else { hr = E_OUTOFMEMORY; CoTaskMemFree(pszProvider2); } } CoTaskMemFree(pszAction2); }
return hr; }
HRESULT CContentBase::_EnumHandlerHelper(IAutoplayHandler* piah) { IEnumAutoplayHandler* penum; if (S_OK == piah->EnumHandlers(&penum)) { LPWSTR pszHandler; LPWSTR pszAction; LPWSTR pszProvider; LPWSTR pszIconLocation; while (S_OK == penum->Next(&pszHandler, &pszAction, &pszProvider, &pszIconLocation)) { // Do not free the strings from EnumHandlers
// CHandlerData will free them in its destructor
CHandlerData *pdata; HRESULT hr = _CreateHandlerData(pszAction, pszProvider, &pszHandler, &pszIconLocation, &pdata); if (SUCCEEDED(hr)) { hr = _dpaHandlerData.AddHandler(pdata); if (FAILED(hr)) { pdata->Release(); } } else { CoTaskMemFree(pszHandler); CoTaskMemFree(pszIconLocation); } CoTaskMemFree(pszProvider); CoTaskMemFree(pszAction); }
penum->Release(); }
return S_OK; }
HRESULT _CreateLegacyHandler(IAssociationElement *pae, PCWSTR pszAction, CHandlerData **ppdata) { *ppdata = 0; PWSTR pszIcon; HRESULT hr = pae->QueryString(AQVS_APPLICATION_PATH, NULL, &pszIcon); if(SUCCEEDED(hr)) { PWSTR pszFriendly; hr = pae->QueryString(AQVS_APPLICATION_FRIENDLYNAME, NULL, &pszFriendly); if(SUCCEEDED(hr)) { PWSTR pszHandler; hr = SHStrDup(TEXT("AutoplayLegacyHandler"), &pszHandler); if (SUCCEEDED(hr)) { hr = _CreateHandlerData(pszAction, pszFriendly, &pszHandler, &pszIcon, ppdata); CoTaskMemFree(pszHandler); } CoTaskMemFree(pszFriendly); } CoTaskMemFree(pszIcon); }
return hr; }
CHandlerData* CContentBase::GetHandlerData(int i) { CHandlerData* phandlerdata = _dpaHandlerData.GetPtr(i);
if (phandlerdata) { phandlerdata->AddRef(); }
return phandlerdata; }
HRESULT CContentBase::_AddLegacyHandler(DWORD dwContentType) { HRESULT hr = S_FALSE;
if (dwContentType & (CT_CDAUDIO | CT_DVDMOVIE)) { LPCWSTR pszProgID; LPCWSTR pszAction;
if (dwContentType & CT_CDAUDIO) { pszProgID = TEXT("AudioCD"); pszAction = TEXT("@%SystemRoot%\\system32\\shell32.dll,-17171"); } else { ASSERT(dwContentType & CT_DVDMOVIE); pszProgID = TEXT("DVD"); pszAction = TEXT("@%SystemRoot%\\system32\\shell32.dll,-17172"); }
IAssociationElement * pae; hr = AssocElemCreateForClass(&CLSID_AssocProgidElement, pszProgID, &pae); if (SUCCEEDED(hr)) { PWSTR pszCommand; hr = pae->QueryString(AQVS_COMMAND, NULL, &pszCommand); if (SUCCEEDED(hr)) { // legacy guys have a command or we dont add them
// we expect new guys to be responsible and add themselves
// to the autoplay handlers key
if (!_dpaHandlerData.IsDuplicateCommand(pszCommand)) { CHandlerData* pdata; hr = _CreateLegacyHandler(pae, pszAction, &pdata); if (SUCCEEDED(hr)) { hr = _dpaHandlerData.AddHandler(pdata); if (FAILED(hr)) { pdata->Release(); } } } CoTaskMemFree(pszCommand); } pae->Release(); }
}
return hr; }
HRESULT CContentTypeData::Init(LPCWSTR pszDrive, DWORD dwContentType) { HRESULT hr;
_dwContentType = dwContentType;
hr = _GetContentTypeHandler(_dwContentType, _szContentTypeHandler, ARRAYSIZE(_szContentTypeHandler));
if (SUCCEEDED(hr)) { hr = _GetContentTypeInfo(_dwContentType, _szIconLabel, ARRAYSIZE(_szIconLabel), _szIconLocation, ARRAYSIZE(_szIconLocation));
if (SUCCEEDED(hr)) { hr = StringCchCopy(_szDrive, ARRAYSIZE(_szDrive), pszDrive);
if (SUCCEEDED(hr)) { IAutoplayHandler* piah;
hr = _GetAutoplayHandler(_szDrive, TEXT("ContentArrival"), _szContentTypeHandler, &piah);
if (SUCCEEDED(hr)) { hr = piah->GetDefaultHandler(&_pszHandlerDefaultOriginal);
if (SUCCEEDED(hr)) { if (S_FALSE != hr) { _dwHandlerDefaultFlags = HANDLERDEFAULT_GETFLAGS(hr); }
// SHStrDup (we want CoTaskMemAlloc)
hr = SHStrDup(_pszHandlerDefaultOriginal, &_pszHandlerDefault); }
if (SUCCEEDED(hr)) { if (_dpaHandlerData.Create(4)) { hr = _EnumHandlerHelper(piah); if (SUCCEEDED(hr)) { _AddLegacyHandler(dwContentType); } } }
piah->Release(); } } } }
return hr; }
HRESULT CContentTypeCBItem::GetText(LPWSTR pszText, DWORD cchText) { HRESULT hr; CContentTypeData* pdata = GetData(); if (pdata) { hr = StringCchCopy(pszText, cchText, pdata->_szIconLabel); pdata->Release(); } else { *pszText = NULL; hr = S_FALSE; }
return hr; }
HRESULT CContentTypeCBItem::GetIconLocation(LPWSTR pszIconLocation, DWORD cchIconLocation) { HRESULT hr; CContentTypeData* pdata = GetData(); if (pdata) { hr = StringCchCopy(pszIconLocation, cchIconLocation, pdata->_szIconLocation); pdata->Release(); } else { *pszIconLocation = NULL; hr = S_FALSE; }
return hr; }
CHandlerData::~CHandlerData() { if (_pszHandler) { CoTaskMemFree((void*)_pszHandler); } if (_pszHandlerFriendlyName) { CoTaskMemFree((void*)_pszHandlerFriendlyName); } if (_pszIconLocation) { CoTaskMemFree((void*)_pszIconLocation); } if (_pszTileText) { CoTaskMemFree(_pszTileText); } }
void CHandlerData::Init(PWSTR pszHandler, PWSTR pszHandlerFriendlyName, PWSTR pszIconLocation, PWSTR pszTileText) { _pszHandler = pszHandler; _pszHandlerFriendlyName = pszHandlerFriendlyName; _pszIconLocation = pszIconLocation; _pszTileText = pszTileText; // WE CANT FAIL
}
void CHandlerData::UpdateDirty() { // nothing to do
} HRESULT CHandlerLVItem::GetText(LPWSTR pszText, DWORD cchText) { HRESULT hr; CHandlerData* pdata = GetData(); if (pdata) { hr = StringCchCopy(pszText, cchText, pdata->_pszHandlerFriendlyName); pdata->Release(); } else { *pszText = NULL; hr = S_FALSE; }
return hr; }
HRESULT CHandlerLVItem::GetIconLocation(LPWSTR pszIconLocation, DWORD cchIconLocation) { HRESULT hr; CHandlerData* pdata = GetData(); if (pdata) { hr = StringCchCopy(pszIconLocation, cchIconLocation, pdata->_pszIconLocation); pdata->Release(); } else { *pszIconLocation = NULL; hr = S_FALSE; }
return hr; }
HRESULT CHandlerLVItem::GetTileText(int i, LPWSTR pszTileText, DWORD cchTileText) { HRESULT hr = S_FALSE; CHandlerData* pdata = GetData();
*pszTileText = NULL; hr = S_FALSE;
// we dont support anything but zero
ASSERT(0 == i); if (pdata) { if (pdata->_pszTileText) { hr = StringCchCopy(pszTileText, cchTileText, pdata->_pszTileText); } pdata->Release(); }
return hr; }
// We are erring on the side of safety here by giving FALSE positives
// sometimes. This could be optimized to consider if we have diff handler
// just because one is missing.
void CNoContentData::UpdateDirty() { BOOL fDirty = _AreHandlersDifferent(_pszHandlerDefault, _pszHandlerDefaultOriginal) || (HANDLERDEFAULT_DEFAULTSAREDIFFERENT & _dwHandlerDefaultFlags);
_SetDirty(fDirty); }
HRESULT CNoContentData::CommitChangesToStorage() { HRESULT hr = S_OK;
if (_AreHandlersDifferent(_pszHandlerDefault, _pszHandlerDefaultOriginal) || (HANDLERDEFAULT_DEFAULTSAREDIFFERENT & _dwHandlerDefaultFlags)) { // Yep, changed
IAutoplayHandler* piah;
hr = _GetAutoplayHandlerNoContent(_szDeviceID, TEXT("DeviceArrival"), &piah); if (SUCCEEDED(hr)) { if (!_fSoftCommit) { hr = piah->SetDefaultHandler(_pszHandlerDefault); } else { WCHAR szHandler[MAX_HANDLER + ARRAYSIZE(SOFTPREFIX)];
lstrcpyn(szHandler, SOFTPREFIX, ARRAYSIZE(szHandler)); StrCatBuff(szHandler, _pszHandlerDefault, ARRAYSIZE(szHandler));
hr = piah->SetDefaultHandler(szHandler); }
piah->Release(); } }
if (SUCCEEDED(hr)) { _SetHandlerDefault(&_pszHandlerDefaultOriginal, _pszHandlerDefault); }
return hr; }
CNoContentData::~CNoContentData() { if (_pszHandlerDefaultOriginal) { CoTaskMemFree(_pszHandlerDefaultOriginal); }
if (_pszHandlerDefault) { CoTaskMemFree(_pszHandlerDefault); }
if (_pszIconLabel) { CoTaskMemFree((void*)_pszIconLabel); }
if (_pszIconLocation) { CoTaskMemFree((void*)_pszIconLocation); } }
HRESULT _MakeDeviceLabel(LPCWSTR pszSource, LPWSTR* ppszDest) { WCHAR szDeviceName[250];
HRESULT hr = SHLoadIndirectString(pszSource, szDeviceName, ARRAYSIZE(szDeviceName), NULL); if (SUCCEEDED(hr)) { hr = SHStrDup(szDeviceName, ppszDest); }
return hr; }
HRESULT CNoContentData::Init(LPCWSTR pszDeviceID) { HRESULT hr = StringCchCopy(_szDeviceID, ARRAYSIZE(_szDeviceID), pszDeviceID);
if (SUCCEEDED(hr)) { IAutoplayHandler* piah; hr = _GetAutoplayHandlerNoContent(_szDeviceID, TEXT("DeviceArrival"), &piah); if (SUCCEEDED(hr)) { hr = piah->GetDefaultHandler(&_pszHandlerDefaultOriginal);
if (SUCCEEDED(hr)) { if (S_FALSE != hr) { _dwHandlerDefaultFlags = HANDLERDEFAULT_GETFLAGS(hr); }
// SHStrDup (we want CoTaskMemAlloc)
hr = SHStrDup(_pszHandlerDefaultOriginal, &_pszHandlerDefault); }
if (SUCCEEDED(hr)) { if (_dpaHandlerData.Create(4)) { hr = _EnumHandlerHelper(piah); } }
piah->Release(); }
if (SUCCEEDED(hr)) { IHWDeviceCustomProperties* pihwdevcp; hr = GetDeviceProperties(_szDeviceID, &pihwdevcp); if (SUCCEEDED(hr)) { LPWSTR pszIconLabel; hr = pihwdevcp->GetStringProperty(TEXT("Label"), &pszIconLabel); if (SUCCEEDED(hr)) { hr = _MakeDeviceLabel(pszIconLabel, &_pszIconLabel); if (SUCCEEDED(hr)) { WORD_BLOB* pblob;
hr = pihwdevcp->GetMultiStringProperty(TEXT("Icons"), TRUE, &pblob); if (SUCCEEDED(hr)) { hr = SHStrDup(pblob->asData, &_pszIconLocation);
CoTaskMemFree(pblob); }
CoTaskMemFree(pszIconLabel); } }
pihwdevcp->Release(); } } }
return hr; }
|