Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

709 lines
18 KiB

  1. #include "shellprv.h"
  2. #include "ids.h"
  3. #include "hwcmmn.h"
  4. #include "apdlglog.h"
  5. #include "mtptl.h"
  6. BOOL _AreHandlersDifferent(LPCWSTR /*pszOriginal*/, LPCWSTR /*pszNew*/)
  7. {
  8. return TRUE;
  9. }
  10. CHandlerDataArray::~CHandlerDataArray()
  11. {
  12. if (IsDPASet())
  13. {
  14. DestroyCallback(_ReleaseHandler, NULL);
  15. }
  16. }
  17. BOOL CHandlerDataArray::_IsDemotedHandler(PCWSTR pszHandler)
  18. {
  19. return ((0 == StrCmpIW(pszHandler, L"MSTakeNoAction"))
  20. || (0 == StrCmpIW(pszHandler, L"MSOpenFolder")));
  21. }
  22. HRESULT CHandlerDataArray::AddHandler(CHandlerData *pdata)
  23. {
  24. // always insert ahead of TakeNoAction and OpenFolder
  25. int iInsert;
  26. if (!_IsDemotedHandler(pdata->_pszHandler))
  27. {
  28. int c = GetPtrCount();
  29. for (iInsert = 0; iInsert < c; iInsert++)
  30. {
  31. if (_IsDemotedHandler(GetPtr(iInsert)->_pszHandler))
  32. {
  33. // insert here
  34. break;
  35. }
  36. }
  37. iInsert = InsertPtr(iInsert, pdata);
  38. }
  39. else
  40. {
  41. iInsert = AppendPtr(pdata);
  42. }
  43. return DPA_ERR != iInsert ? S_OK : E_OUTOFMEMORY;
  44. }
  45. BOOL CHandlerDataArray::IsDuplicateCommand(PCWSTR pszCommand)
  46. {
  47. WCHAR sz[MAX_PATH * 2];
  48. BOOL fRet = FALSE;
  49. int c = GetPtrCount();
  50. for (int i = 0; i < c; i++)
  51. {
  52. CHandlerData *pdata = GetPtr(i);
  53. if (SUCCEEDED(pdata->_GetCommand(sz, ARRAYSIZE(sz))))
  54. {
  55. fRet = (0 == StrCmpIW(pszCommand, sz));
  56. if (fRet)
  57. break;
  58. }
  59. }
  60. return fRet;
  61. }
  62. // We are erring on the side of safety here by giving FALSE positives
  63. // sometimes. This could be optimized to consider if we have diff handler
  64. // just because one is missing.
  65. void CContentTypeData::UpdateDirty()
  66. {
  67. BOOL fDirty = _AreHandlersDifferent(_pszHandlerDefault, _pszHandlerDefaultOriginal) ||
  68. (HANDLERDEFAULT_DEFAULTSAREDIFFERENT & _dwHandlerDefaultFlags);
  69. _SetDirty(fDirty);
  70. }
  71. #define SOFTPREFIX TEXT("[soft]")
  72. HRESULT CContentTypeData::CommitChangesToStorage()
  73. {
  74. HRESULT hr = S_OK;
  75. if (_AreHandlersDifferent(_pszHandlerDefault, _pszHandlerDefaultOriginal) ||
  76. (HANDLERDEFAULT_DEFAULTSAREDIFFERENT & _dwHandlerDefaultFlags))
  77. {
  78. // Yep, changed
  79. IAutoplayHandler* piah;
  80. hr = _GetAutoplayHandler(_szDrive, TEXT("ContentArrival"), _szContentTypeHandler, &piah);
  81. if (SUCCEEDED(hr))
  82. {
  83. if (!_fSoftCommit)
  84. {
  85. hr = piah->SetDefaultHandler(_pszHandlerDefault);
  86. }
  87. else
  88. {
  89. WCHAR szHandler[MAX_HANDLER + ARRAYSIZE(SOFTPREFIX)];
  90. lstrcpyn(szHandler, SOFTPREFIX, ARRAYSIZE(szHandler));
  91. StrCatBuff(szHandler, _pszHandlerDefault, ARRAYSIZE(szHandler));
  92. hr = piah->SetDefaultHandler(szHandler);
  93. }
  94. piah->Release();
  95. }
  96. }
  97. if (SUCCEEDED(hr))
  98. {
  99. _SetHandlerDefault(&_pszHandlerDefaultOriginal, _pszHandlerDefault);
  100. }
  101. return hr;
  102. }
  103. CContentTypeData::~CContentTypeData()
  104. {
  105. if (_pszHandlerDefaultOriginal)
  106. {
  107. CoTaskMemFree(_pszHandlerDefaultOriginal);
  108. }
  109. if (_pszHandlerDefault)
  110. {
  111. CoTaskMemFree(_pszHandlerDefault);
  112. }
  113. }
  114. HRESULT _MakeActionString(LPCWSTR pszAction, LPWSTR* ppszAction2)
  115. {
  116. *ppszAction2 = NULL;
  117. WCHAR szAction[250];
  118. HRESULT hr = SHLoadIndirectString(pszAction, szAction, ARRAYSIZE(szAction), NULL);
  119. if (SUCCEEDED(hr))
  120. {
  121. hr = SHStrDup(szAction, ppszAction2);
  122. }
  123. return hr;
  124. }
  125. HRESULT _MakeProviderString(LPCWSTR pszProvider, LPWSTR* ppszProvider2)
  126. {
  127. WCHAR szProviderNonMUI[250];
  128. HRESULT hr = SHLoadIndirectString(pszProvider, szProviderNonMUI, ARRAYSIZE(szProviderNonMUI), NULL);
  129. if (SUCCEEDED(hr))
  130. {
  131. WCHAR szUsing[50];
  132. if (LoadString(g_hinst, IDS_AP_USING, szUsing, ARRAYSIZE(szUsing)))
  133. {
  134. WCHAR szProvider2[250];
  135. hr = StringCchPrintf(szProvider2, ARRAYSIZE(szProvider2), szUsing, szProviderNonMUI);
  136. if (SUCCEEDED(hr))
  137. {
  138. hr = SHStrDup(szProvider2, ppszProvider2);
  139. }
  140. }
  141. else
  142. {
  143. hr = E_FAIL;
  144. }
  145. }
  146. return hr;
  147. }
  148. inline void _CoTaskMemFree(void* pv)
  149. {
  150. if (pv)
  151. {
  152. CoTaskMemFree(pv);
  153. }
  154. }
  155. HRESULT _CreateHandlerData( PCWSTR pszAction,
  156. PCWSTR pszProvider,
  157. PWSTR *ppszHandler, // IN/OUT
  158. PWSTR *ppszIcon, // IN/OUT
  159. CHandlerData **ppdata)
  160. {
  161. *ppdata = 0;
  162. LPWSTR pszAction2 = NULL;
  163. HRESULT hr = _MakeActionString(pszAction, &pszAction2);
  164. if (SUCCEEDED(hr))
  165. {
  166. LPWSTR pszProvider2 = NULL;
  167. // Special case this guy, we don't want to say:
  168. // "Take no action, using Microsoft Windows"
  169. if (lstrcmp(*ppszHandler, TEXT("MSTakeNoAction")))
  170. {
  171. hr = _MakeProviderString(pszProvider, &pszProvider2);
  172. }
  173. // else this is NULL, and ignored
  174. if (SUCCEEDED(hr))
  175. {
  176. *ppdata = new CHandlerData();
  177. if (*ppdata)
  178. {
  179. // give away ownership of these allocations
  180. (*ppdata)->Init(*ppszHandler, pszAction2,
  181. *ppszIcon, pszProvider2);
  182. *ppszHandler = NULL;
  183. *ppszIcon = NULL;
  184. pszAction2 = NULL;
  185. pszProvider2 = NULL;
  186. }
  187. else
  188. {
  189. hr = E_OUTOFMEMORY;
  190. CoTaskMemFree(pszProvider2);
  191. }
  192. }
  193. CoTaskMemFree(pszAction2);
  194. }
  195. return hr;
  196. }
  197. HRESULT CContentBase::_EnumHandlerHelper(IAutoplayHandler* piah)
  198. {
  199. IEnumAutoplayHandler* penum;
  200. if (S_OK == piah->EnumHandlers(&penum))
  201. {
  202. LPWSTR pszHandler;
  203. LPWSTR pszAction;
  204. LPWSTR pszProvider;
  205. LPWSTR pszIconLocation;
  206. while (S_OK == penum->Next(&pszHandler, &pszAction, &pszProvider,
  207. &pszIconLocation))
  208. {
  209. // Do not free the strings from EnumHandlers
  210. // CHandlerData will free them in its destructor
  211. CHandlerData *pdata;
  212. HRESULT hr = _CreateHandlerData(pszAction, pszProvider, &pszHandler, &pszIconLocation, &pdata);
  213. if (SUCCEEDED(hr))
  214. {
  215. hr = _dpaHandlerData.AddHandler(pdata);
  216. if (FAILED(hr))
  217. {
  218. pdata->Release();
  219. }
  220. }
  221. else
  222. {
  223. CoTaskMemFree(pszHandler);
  224. CoTaskMemFree(pszIconLocation);
  225. }
  226. CoTaskMemFree(pszProvider);
  227. CoTaskMemFree(pszAction);
  228. }
  229. penum->Release();
  230. }
  231. return S_OK;
  232. }
  233. HRESULT _CreateLegacyHandler(IAssociationElement *pae, PCWSTR pszAction, CHandlerData **ppdata)
  234. {
  235. *ppdata = 0;
  236. PWSTR pszIcon;
  237. HRESULT hr = pae->QueryString(AQVS_APPLICATION_PATH, NULL, &pszIcon);
  238. if(SUCCEEDED(hr))
  239. {
  240. PWSTR pszFriendly;
  241. hr = pae->QueryString(AQVS_APPLICATION_FRIENDLYNAME, NULL, &pszFriendly);
  242. if(SUCCEEDED(hr))
  243. {
  244. PWSTR pszHandler;
  245. hr = SHStrDup(TEXT("AutoplayLegacyHandler"), &pszHandler);
  246. if (SUCCEEDED(hr))
  247. {
  248. hr = _CreateHandlerData(pszAction, pszFriendly, &pszHandler, &pszIcon, ppdata);
  249. CoTaskMemFree(pszHandler);
  250. }
  251. CoTaskMemFree(pszFriendly);
  252. }
  253. CoTaskMemFree(pszIcon);
  254. }
  255. return hr;
  256. }
  257. CHandlerData* CContentBase::GetHandlerData(int i)
  258. {
  259. CHandlerData* phandlerdata = _dpaHandlerData.GetPtr(i);
  260. if (phandlerdata)
  261. {
  262. phandlerdata->AddRef();
  263. }
  264. return phandlerdata;
  265. }
  266. HRESULT CContentBase::_AddLegacyHandler(DWORD dwContentType)
  267. {
  268. HRESULT hr = S_FALSE;
  269. if (dwContentType & (CT_CDAUDIO | CT_DVDMOVIE))
  270. {
  271. LPCWSTR pszProgID;
  272. LPCWSTR pszAction;
  273. if (dwContentType & CT_CDAUDIO)
  274. {
  275. pszProgID = TEXT("AudioCD");
  276. pszAction = TEXT("@%SystemRoot%\\system32\\shell32.dll,-17171");
  277. }
  278. else
  279. {
  280. ASSERT(dwContentType & CT_DVDMOVIE);
  281. pszProgID = TEXT("DVD");
  282. pszAction = TEXT("@%SystemRoot%\\system32\\shell32.dll,-17172");
  283. }
  284. IAssociationElement * pae;
  285. hr = AssocElemCreateForClass(&CLSID_AssocProgidElement, pszProgID, &pae);
  286. if (SUCCEEDED(hr))
  287. {
  288. PWSTR pszCommand;
  289. hr = pae->QueryString(AQVS_COMMAND, NULL, &pszCommand);
  290. if (SUCCEEDED(hr))
  291. {
  292. // legacy guys have a command or we dont add them
  293. // we expect new guys to be responsible and add themselves
  294. // to the autoplay handlers key
  295. if (!_dpaHandlerData.IsDuplicateCommand(pszCommand))
  296. {
  297. CHandlerData* pdata;
  298. hr = _CreateLegacyHandler(pae, pszAction, &pdata);
  299. if (SUCCEEDED(hr))
  300. {
  301. hr = _dpaHandlerData.AddHandler(pdata);
  302. if (FAILED(hr))
  303. {
  304. pdata->Release();
  305. }
  306. }
  307. }
  308. CoTaskMemFree(pszCommand);
  309. }
  310. pae->Release();
  311. }
  312. }
  313. return hr;
  314. }
  315. HRESULT CContentTypeData::Init(LPCWSTR pszDrive, DWORD dwContentType)
  316. {
  317. HRESULT hr;
  318. _dwContentType = dwContentType;
  319. hr = _GetContentTypeHandler(_dwContentType, _szContentTypeHandler,
  320. ARRAYSIZE(_szContentTypeHandler));
  321. if (SUCCEEDED(hr))
  322. {
  323. hr = _GetContentTypeInfo(_dwContentType, _szIconLabel, ARRAYSIZE(_szIconLabel),
  324. _szIconLocation, ARRAYSIZE(_szIconLocation));
  325. if (SUCCEEDED(hr))
  326. {
  327. hr = StringCchCopy(_szDrive, ARRAYSIZE(_szDrive), pszDrive);
  328. if (SUCCEEDED(hr))
  329. {
  330. IAutoplayHandler* piah;
  331. hr = _GetAutoplayHandler(_szDrive, TEXT("ContentArrival"),
  332. _szContentTypeHandler, &piah);
  333. if (SUCCEEDED(hr))
  334. {
  335. hr = piah->GetDefaultHandler(&_pszHandlerDefaultOriginal);
  336. if (SUCCEEDED(hr))
  337. {
  338. if (S_FALSE != hr)
  339. {
  340. _dwHandlerDefaultFlags = HANDLERDEFAULT_GETFLAGS(hr);
  341. }
  342. // SHStrDup (we want CoTaskMemAlloc)
  343. hr = SHStrDup(_pszHandlerDefaultOriginal, &_pszHandlerDefault);
  344. }
  345. if (SUCCEEDED(hr))
  346. {
  347. if (_dpaHandlerData.Create(4))
  348. {
  349. hr = _EnumHandlerHelper(piah);
  350. if (SUCCEEDED(hr))
  351. {
  352. _AddLegacyHandler(dwContentType);
  353. }
  354. }
  355. }
  356. piah->Release();
  357. }
  358. }
  359. }
  360. }
  361. return hr;
  362. }
  363. HRESULT CContentTypeCBItem::GetText(LPWSTR pszText, DWORD cchText)
  364. {
  365. HRESULT hr;
  366. CContentTypeData* pdata = GetData();
  367. if (pdata)
  368. {
  369. hr = StringCchCopy(pszText, cchText, pdata->_szIconLabel);
  370. pdata->Release();
  371. }
  372. else
  373. {
  374. *pszText = NULL;
  375. hr = S_FALSE;
  376. }
  377. return hr;
  378. }
  379. HRESULT CContentTypeCBItem::GetIconLocation(LPWSTR pszIconLocation, DWORD cchIconLocation)
  380. {
  381. HRESULT hr;
  382. CContentTypeData* pdata = GetData();
  383. if (pdata)
  384. {
  385. hr = StringCchCopy(pszIconLocation, cchIconLocation, pdata->_szIconLocation);
  386. pdata->Release();
  387. }
  388. else
  389. {
  390. *pszIconLocation = NULL;
  391. hr = S_FALSE;
  392. }
  393. return hr;
  394. }
  395. CHandlerData::~CHandlerData()
  396. {
  397. if (_pszHandler)
  398. {
  399. CoTaskMemFree((void*)_pszHandler);
  400. }
  401. if (_pszHandlerFriendlyName)
  402. {
  403. CoTaskMemFree((void*)_pszHandlerFriendlyName);
  404. }
  405. if (_pszIconLocation)
  406. {
  407. CoTaskMemFree((void*)_pszIconLocation);
  408. }
  409. if (_pszTileText)
  410. {
  411. CoTaskMemFree(_pszTileText);
  412. }
  413. }
  414. void CHandlerData::Init(PWSTR pszHandler, PWSTR pszHandlerFriendlyName,
  415. PWSTR pszIconLocation, PWSTR pszTileText)
  416. {
  417. _pszHandler = pszHandler;
  418. _pszHandlerFriendlyName = pszHandlerFriendlyName;
  419. _pszIconLocation = pszIconLocation;
  420. _pszTileText = pszTileText;
  421. // WE CANT FAIL
  422. }
  423. void CHandlerData::UpdateDirty()
  424. {
  425. // nothing to do
  426. }
  427. HRESULT CHandlerLVItem::GetText(LPWSTR pszText, DWORD cchText)
  428. {
  429. HRESULT hr;
  430. CHandlerData* pdata = GetData();
  431. if (pdata)
  432. {
  433. hr = StringCchCopy(pszText, cchText, pdata->_pszHandlerFriendlyName);
  434. pdata->Release();
  435. }
  436. else
  437. {
  438. *pszText = NULL;
  439. hr = S_FALSE;
  440. }
  441. return hr;
  442. }
  443. HRESULT CHandlerLVItem::GetIconLocation(LPWSTR pszIconLocation, DWORD cchIconLocation)
  444. {
  445. HRESULT hr;
  446. CHandlerData* pdata = GetData();
  447. if (pdata)
  448. {
  449. hr = StringCchCopy(pszIconLocation, cchIconLocation, pdata->_pszIconLocation);
  450. pdata->Release();
  451. }
  452. else
  453. {
  454. *pszIconLocation = NULL;
  455. hr = S_FALSE;
  456. }
  457. return hr;
  458. }
  459. HRESULT CHandlerLVItem::GetTileText(int i, LPWSTR pszTileText, DWORD cchTileText)
  460. {
  461. HRESULT hr = S_FALSE;
  462. CHandlerData* pdata = GetData();
  463. *pszTileText = NULL;
  464. hr = S_FALSE;
  465. // we dont support anything but zero
  466. ASSERT(0 == i);
  467. if (pdata)
  468. {
  469. if (pdata->_pszTileText)
  470. {
  471. hr = StringCchCopy(pszTileText, cchTileText, pdata->_pszTileText);
  472. }
  473. pdata->Release();
  474. }
  475. return hr;
  476. }
  477. // We are erring on the side of safety here by giving FALSE positives
  478. // sometimes. This could be optimized to consider if we have diff handler
  479. // just because one is missing.
  480. void CNoContentData::UpdateDirty()
  481. {
  482. BOOL fDirty = _AreHandlersDifferent(_pszHandlerDefault, _pszHandlerDefaultOriginal) ||
  483. (HANDLERDEFAULT_DEFAULTSAREDIFFERENT & _dwHandlerDefaultFlags);
  484. _SetDirty(fDirty);
  485. }
  486. HRESULT CNoContentData::CommitChangesToStorage()
  487. {
  488. HRESULT hr = S_OK;
  489. if (_AreHandlersDifferent(_pszHandlerDefault, _pszHandlerDefaultOriginal) ||
  490. (HANDLERDEFAULT_DEFAULTSAREDIFFERENT & _dwHandlerDefaultFlags))
  491. {
  492. // Yep, changed
  493. IAutoplayHandler* piah;
  494. hr = _GetAutoplayHandlerNoContent(_szDeviceID, TEXT("DeviceArrival"), &piah);
  495. if (SUCCEEDED(hr))
  496. {
  497. if (!_fSoftCommit)
  498. {
  499. hr = piah->SetDefaultHandler(_pszHandlerDefault);
  500. }
  501. else
  502. {
  503. WCHAR szHandler[MAX_HANDLER + ARRAYSIZE(SOFTPREFIX)];
  504. lstrcpyn(szHandler, SOFTPREFIX, ARRAYSIZE(szHandler));
  505. StrCatBuff(szHandler, _pszHandlerDefault, ARRAYSIZE(szHandler));
  506. hr = piah->SetDefaultHandler(szHandler);
  507. }
  508. piah->Release();
  509. }
  510. }
  511. if (SUCCEEDED(hr))
  512. {
  513. _SetHandlerDefault(&_pszHandlerDefaultOriginal, _pszHandlerDefault);
  514. }
  515. return hr;
  516. }
  517. CNoContentData::~CNoContentData()
  518. {
  519. if (_pszHandlerDefaultOriginal)
  520. {
  521. CoTaskMemFree(_pszHandlerDefaultOriginal);
  522. }
  523. if (_pszHandlerDefault)
  524. {
  525. CoTaskMemFree(_pszHandlerDefault);
  526. }
  527. if (_pszIconLabel)
  528. {
  529. CoTaskMemFree((void*)_pszIconLabel);
  530. }
  531. if (_pszIconLocation)
  532. {
  533. CoTaskMemFree((void*)_pszIconLocation);
  534. }
  535. }
  536. HRESULT _MakeDeviceLabel(LPCWSTR pszSource, LPWSTR* ppszDest)
  537. {
  538. WCHAR szDeviceName[250];
  539. HRESULT hr = SHLoadIndirectString(pszSource, szDeviceName, ARRAYSIZE(szDeviceName), NULL);
  540. if (SUCCEEDED(hr))
  541. {
  542. hr = SHStrDup(szDeviceName, ppszDest);
  543. }
  544. return hr;
  545. }
  546. HRESULT CNoContentData::Init(LPCWSTR pszDeviceID)
  547. {
  548. HRESULT hr = StringCchCopy(_szDeviceID, ARRAYSIZE(_szDeviceID), pszDeviceID);
  549. if (SUCCEEDED(hr))
  550. {
  551. IAutoplayHandler* piah;
  552. hr = _GetAutoplayHandlerNoContent(_szDeviceID, TEXT("DeviceArrival"), &piah);
  553. if (SUCCEEDED(hr))
  554. {
  555. hr = piah->GetDefaultHandler(&_pszHandlerDefaultOriginal);
  556. if (SUCCEEDED(hr))
  557. {
  558. if (S_FALSE != hr)
  559. {
  560. _dwHandlerDefaultFlags = HANDLERDEFAULT_GETFLAGS(hr);
  561. }
  562. // SHStrDup (we want CoTaskMemAlloc)
  563. hr = SHStrDup(_pszHandlerDefaultOriginal, &_pszHandlerDefault);
  564. }
  565. if (SUCCEEDED(hr))
  566. {
  567. if (_dpaHandlerData.Create(4))
  568. {
  569. hr = _EnumHandlerHelper(piah);
  570. }
  571. }
  572. piah->Release();
  573. }
  574. if (SUCCEEDED(hr))
  575. {
  576. IHWDeviceCustomProperties* pihwdevcp;
  577. hr = GetDeviceProperties(_szDeviceID, &pihwdevcp);
  578. if (SUCCEEDED(hr))
  579. {
  580. LPWSTR pszIconLabel;
  581. hr = pihwdevcp->GetStringProperty(TEXT("Label"), &pszIconLabel);
  582. if (SUCCEEDED(hr))
  583. {
  584. hr = _MakeDeviceLabel(pszIconLabel, &_pszIconLabel);
  585. if (SUCCEEDED(hr))
  586. {
  587. WORD_BLOB* pblob;
  588. hr = pihwdevcp->GetMultiStringProperty(TEXT("Icons"), TRUE, &pblob);
  589. if (SUCCEEDED(hr))
  590. {
  591. hr = SHStrDup(pblob->asData, &_pszIconLocation);
  592. CoTaskMemFree(pblob);
  593. }
  594. CoTaskMemFree(pszIconLabel);
  595. }
  596. }
  597. pihwdevcp->Release();
  598. }
  599. }
  600. }
  601. return hr;
  602. }