ReactOS 0.4.17-dev-769-g1500a35
elements.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Shell
3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4 * PURPOSE: AssocCreateElement
5 * COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7#include <windef.h>
8#include <shlobj.h>
9#include <shlwapi.h>
10#include <undocshell.h>
11#include <shlobj_undoc.h>
12#include <shlguid_undoc.h>
13#include <shlwapi_undoc.h>
14#include <pathcch.h>
15#include <strsafe.h>
16#include <shellutils.h>
17#include <new>
18#include "evalcmd.h"
19#include "elements.h"
20#include "resource.h"
21
22#include <wine/debug.h>
24
25C_ASSERT(SHELL32_CAssocElement_Version == _WIN32_WINNT_WINXP); // TODO: Follow DLL_EXPORT_VERSION
26
27typedef HRESULT (CALLBACK* QUERY_CALLBACK)(IQuerySourceOld*, ASSOCQUERY query, PCWSTR keyName,
28 PCWSTR valueName, PVOID pValue);
29
30typedef struct QUERYKEYVAL
31{
36
38{
39 { ASSOCQUERY_FRIENDLYAPPNAME, NULL, L"FriendlyTypeName" },
40 { ASSOCQUERY_DEFAULTICON, L"DefaultIcon", NULL },
41};
42
44{
45 { ASSOCQUERY_FRIENDLYAPPNAME, NULL, L"FriendlyTypeName" },
46 { ASSOCQUERY_DEFAULTICON, L"DefaultIcon", NULL },
47 { ASSOCQUERY_CLSID, L"Clsid", NULL },
48 { ASSOCQUERY_PROGID, L"Progid", NULL },
49 { ASSOCQUERY_SHELLEX, L"ShellEx\\%s", NULL },
50};
51
53{
54 { ASSOCQUERY_COMMAND, L"command", NULL },
55 { ASSOCQUERY_DDEEXEC, L"ddeexec", NULL },
56 { ASSOCQUERY_DDEEXEC_IFEXEC, L"ddeexec\\ifexec", NULL },
57 { ASSOCQUERY_DDEEXEC_APPLICATION, L"ddeexec\\application", NULL },
58 { ASSOCQUERY_DDEEXEC_TOPIC, L"ddeexec\\topic", NULL },
59 { ASSOCQUERY_NOACTIVATEHANDLER, L"ddeexec", L"NoActivateHandler" },
60 { ASSOCQUERY_COMMAND_COMMAND, L"command", L"command" },
61 { ASSOCQUERY_VERB_FRIENDLYAPPNAME, NULL, L"FriendlyAppName" },
62};
63
65{
66 { ASSOCQUERY_APPKEY_FRIENDLYAPPNAME, NULL, L"FriendlyAppName" },
67};
68
70{
71 { ASSOCQUERY_SHELLEX, L"ShellEx\\%s", NULL },
72 { ASSOCQUERY_CONTENT_TYPE, NULL, L"Content Type" },
73};
74
75static const QUERYKEYVAL*
77{
78 for (UINT iItem = 0; iItem < cItems; ++iItem)
79 {
80 if (pItems[iItem].query == query)
81 return &pItems[iItem];
82 }
83 return NULL;
84}
85
86static HRESULT SHAllocMUI(PWSTR* ppwsz)
87{
88 WCHAR szOutBuf[1024];
89 HRESULT hr = SHLoadIndirectString(*ppwsz, szOutBuf, _countof(szOutBuf), NULL);
90 CoTaskMemFree(*ppwsz);
92 {
93 *ppwsz = NULL;
94 return hr;
95 }
96 return SHStrDupW(szOutBuf, ppwsz);
97}
98
100{
101 WCHAR szBuff[MAX_PATH];
102 LoadStringW(hInstance, uID, szBuff, _countof(szBuff));
103 return SHStrDupW(szBuff, ppwsz);
104}
105
107 IQuerySourceOld* pSource,
108 PCWSTR key,
109 PCWSTR pszSrc,
111 IQuerySourceOld** ppSource)
112{
113 WCHAR szDest[MAX_PATH];
114 PathCchCombineEx(szDest, _countof(szDest), key, pszSrc, PATHCCH_NONE);
115 return pSource->OpenSource(szDest, bCreate, ppSource);
116}
117
119{
120 WCHAR szDest[MAX_PATH], szBuff[128];
121 HINSTANCE hSHLWAPI = GetModuleHandleW(L"shlwapi.dll");
122
123 if (!lpsz || *lpsz != '.' || !lpsz[1])
124 return _SHAllocLoadString(hSHLWAPI, IDS_FILE, ppwsz);
125
126 CharUpperW(lpsz);
127 LoadStringW(hSHLWAPI, IDS_ANY_FILE, szBuff, _countof(szBuff));
128 StringCchPrintfW(szDest, _countof(szDest), szBuff, lpsz + 1);
129 return SHStrDupW(szDest, ppwsz);
130}
131
132static inline LSTATUS
133_RegQueryString(HKEY hKey, PCWSTR lpSubKey, PWSTR lpData, LONG cchData)
134{
135 LONG cbData = cchData * sizeof(WCHAR);
136 return RegQueryValueW(hKey, lpSubKey, lpData, &cbData);
137}
138
139static LSTATUS
141{
143 if (lpSubKey && *lpSubKey)
145 NULL, &hKey, NULL);
146 else
148 if (error)
149 return error;
150
151 INT cch = lstrlenW(lpString);
152 error = RegSetValueExW(hKey, NULL, 0, REG_SZ, (PBYTE)lpString, (cch + 1) * sizeof(WCHAR));
154 return error;
155}
156
157static HRESULT CALLBACK
159 IQuerySourceOld* pSource,
161 PCWSTR keyName,
162 PCWSTR valueName,
164{
165 return pSource->QueryValueDirect(keyName, valueName, (FLAGGED_BYTE_BLOB**)pValue);
166}
167
168static HRESULT CALLBACK
170 IQuerySourceOld* pSource,
172 PCWSTR keyName,
173 PCWSTR valueName,
175{
176 return pSource->QueryValueDword(keyName, valueName, (PDWORD)pValue);
177}
178
179static HRESULT CALLBACK
181 IQuerySourceOld* pSource,
183 PCWSTR keyName,
184 PCWSTR valueName,
186{
187 return pSource->QueryValueExists(keyName, valueName);
188}
189
190static HRESULT CALLBACK
192 IQuerySourceOld* pSource,
194 PCWSTR keyName,
195 PCWSTR valueName,
197{
198 HRESULT hr = pSource->QueryValueString(keyName, valueName, static_cast<PWSTR*>(pValue));
200 return hr;
201 return SHAllocMUI(static_cast<PWSTR*>(pValue));
202}
203
204static inline HRESULT
205_QuerySourceCreateFromKey(HKEY hKey, PCWSTR lpSubKey, BOOL bCreate, IQuerySourceOld** ppSource)
206{
207 return QuerySourceCreateFromKey(hKey, lpSubKey, bCreate,
208 IID_PPV_ARG(IQuerySourceOld, ppSource));
209}
210
211static HRESULT
213 HKEY hKey,
214 PCWSTR key1,
215 PCWSTR key2,
216 IQuerySourceOld** ppSource)
217{
218 WCHAR szBuff[MAX_PATH];
219
220 if (key1)
221 PathCchCombineEx(szBuff, _countof(szBuff), key1, key2, PATHCCH_NONE);
222 else
223 StringCchCopyW(szBuff, _countof(szBuff), key2);
224
225 return _QuerySourceCreateFromKey(hKey, szBuff, FALSE, ppSource);
226}
227
228static HRESULT
230{
231 *phkResult = NULL;
232 if (!hKey)
234
236 if ( bCreate )
237 error = RegCreateKeyExW(hKey, lpSubKey, 0, NULL, 0, MAXIMUM_ALLOWED, NULL,
238 phkResult, NULL);
239 else
240 error = RegOpenKeyExW(hKey, lpSubKey, 0, MAXIMUM_ALLOWED, phkResult);
241
242 if (error == ERROR_SUCCESS)
243 return S_OK;
244
246}
247
249{
250 HKEY hKeyBase;
253 return NULL;
254
255 WCHAR szData[64];
256 DWORD cbData = sizeof(szData);
257 if (StrCmpIW(L"Excel.Sheet.8", psz) == 0)
258 return hKeyBase;
259
260 LSTATUS error = SHGetValueW(hKeyBase, L"CurVer", NULL, NULL, szData, &cbData);
261 if (error || cbData <= 2)
262 return hKeyBase;
263
264 HKEY hKeyCurVer;
265 hr = _AssocOpenRegKey(HKEY_CLASSES_ROOT, szData, &hKeyCurVer, FALSE);
267 return hKeyBase;
268
269 HKEY hKeyShell;
270 hr = _AssocOpenRegKey(hKeyCurVer, L"shell", &hKeyShell, FALSE);
272 {
273 hr = _AssocOpenRegKey(hKeyBase, L"shell", &hKeyShell, FALSE);
275 {
276 RegCloseKey(hKeyBase);
277 return hKeyCurVer;
278 }
279
280 RegCloseKey(hKeyShell);
281 RegCloseKey(hKeyCurVer);
282 return hKeyBase;
283 }
284
285 RegCloseKey(hKeyShell);
286 RegCloseKey(hKeyBase);
287 return hKeyCurVer;
288}
289
290static inline void _MakeApplicationsKey(PCWSTR pszPath, PWSTR pszDest, UINT cchDest)
291{
292 HRESULT hr = PathCchCombineEx(pszDest, cchDest, L"Applications", pszPath, PATHCCH_NONE);
294 return;
295
296 PathCchAddExtension(pszDest, cchDest, L".exe");
297}
298
299static inline BOOL _ParamIsApp(PCWSTR psz)
300{
301 return !StrCmpNW(psz, L"%1", 2) || !StrCmpNW(psz, L"\"%1\"", 4);
302}
303
305{
306 DWORD attrs;
309 return S_OK;
310}
311
312static HRESULT _ExeFromCmd(PCWSTR pszCmdTemplate, PWSTR* ppszApplication)
313{
314 if (_ParamIsApp(pszCmdTemplate))
315 return SHStrDupW(L"%1", ppszApplication);
316
317 PWSTR pszParameters = NULL;
318 HRESULT hr = SHEvaluateSystemCommandTemplate(pszCmdTemplate, ppszApplication,
319 NULL, &pszParameters);
321 return hr;
322
323 if (hr != S_OK || StrCmpIW(PathFindFileNameW(*ppszApplication), L"rundll32.exe") != 0)
324 {
325 CoTaskMemFree(pszParameters);
326 return hr;
327 }
328
329 CoTaskMemFree(*ppszApplication);
330 *ppszApplication = NULL;
331
332 PWSTR pchComma = StrChrW(pszParameters, L',');
333 if (!pchComma)
334 {
336 CoTaskMemFree(pszParameters);
337 return hr;
338 }
339
340 WCHAR szExe[MAX_PATH];
341 hr = _PathCopyExeAndTrimWhiteSpaces(szExe, _countof(szExe), pszParameters,
342 pchComma - pszParameters);
344 {
345 CoTaskMemFree(pszParameters);
346 return hr;
347 }
348
349 PathUnquoteSpacesW(szExe);
350
351 PathCchAddExtension(szExe, _countof(szExe), L".dll");
352
353 if (PathIsAbsolute(szExe))
354 {
355 hr = _PathFileExists(szExe);
356 }
357 else if (PathIsFileSpecW(szExe))
358 {
359 hr = _PathFindInSystem(szExe, _countof(szExe));
360 }
361 else
362 {
363 CoTaskMemFree(pszParameters);
365 }
366
367 if (SUCCEEDED(hr))
368 hr = SHStrDupW(szExe, ppszApplication);
369
370 CoTaskMemFree(pszParameters);
371 return hr;
372}
373
374/******************************************************************************
375 * CAssocElement
376 */
378 : public IObjectWithQuerySourceOld
379 , public IAssociationElementOld
380{
381protected:
383 IQuerySourceOld* m_pSource = NULL;
384
387 const QUERYKEYVAL* pItems,
388 UINT cItems,
389 IQuerySourceOld* pQS,
391 PCWSTR valueName,
392 PVOID pValue);
393
396 IQuerySourceOld* pSource,
399 PCWSTR valueName,
400 PVOID pValue);
401
402public:
403 virtual ~CAssocElement();
404
405 /*** IUnknown ***/
409 /*** IObjectWithQuerySourceOld ***/
410 STDMETHODIMP SetSource(IQuerySourceOld* pSource) override;
411 STDMETHODIMP GetSource(REFIID riid, PVOID* ppSource) override;
412 /*** IAssociationElementOld ***/
413 STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR* ppszValue) override;
414 STDMETHODIMP QueryDword(ASSOCQUERY query, PCWSTR key, DWORD* pdwValue) override;
416 STDMETHODIMP QueryDirect(ASSOCQUERY query, PCWSTR key, FLAGGED_BYTE_BLOB** ppBlob) override;
418
419protected:
420 virtual UINT _GetQueryKeyVal(const QUERYKEYVAL** ppItems);
421};
422
423/******************************************************************************
424 * CAssocShellElement
425 */
427 : public CAssocElement
428 , public IPersistString2
429{
430protected:
432 WCHAR m_szBuff[64] = L"";
433
434 UINT _GetQueryKeyVal(const QUERYKEYVAL** ppItems) override;
435 HRESULT _DefaultVerbSource(IQuerySourceOld** ppSource);
436
437public:
439
440 /*** IUnknown ***/
444 /*** IAssociationElementOld ***/
445 STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR* ppszValue) override;
446 STDMETHODIMP QueryDword(ASSOCQUERY query, PCWSTR key, DWORD* pdwValue) override;
448 STDMETHODIMP QueryDirect(ASSOCQUERY query, PCWSTR key, FLAGGED_BYTE_BLOB** ppBlob) override;
450 /*** IPersist ***/
451 STDMETHODIMP GetClassID(CLSID* pClassID) override;
452 /*** IPersistString2 ***/
453 STDMETHODIMP SetString(PCWSTR psz) override;
454 STDMETHODIMP GetString(PWSTR* ppsz) override;
455
457 virtual HRESULT _InitSource();
458 virtual BOOL _IsAppSource();
459 virtual HRESULT _GetVerbDelegate(PCWSTR pszSrc, IAssociationElementOld** ppElement);
460};
461
462/******************************************************************************
463 * CAssocShellVerbElement
464 */
466 : public CAssocElement
467{
468protected:
470
471 UINT _GetQueryKeyVal(const QUERYKEYVAL** ppItems) override;
473
474public:
475 CAssocShellVerbElement(BOOL bAppSource);
476
479};
480
481/******************************************************************************
482 * CAssocApplicationElement
483 */
485 : public CAssocShellElement
486{
487protected:
489
490 UINT _GetQueryKeyVal(const QUERYKEYVAL** ppItems) override;
491 HRESULT _InitSource() override;
493
494public:
495 STDMETHODIMP GetClassID(CLSID* pClsid) override;
498};
499
500/******************************************************************************
501 * CAssocProgidElement
502 */
504 : public CAssocShellElement
505{
506 IQuerySourceOld* m_pSource2 = NULL;
507
508public:
509 ~CAssocProgidElement() override;
510
511 /*** IAssociationElementOld ***/
512 STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR* ppszValue) override;
513 /*** IPersist ***/
514 STDMETHODIMP GetClassID(CLSID* pClassID) override;
515
516 BOOL _UseEnumForDefaultVerb() override;
517 HRESULT _InitSource() override;
518};
519
520/******************************************************************************
521 * CAssocClsidElement
522 */
524 : public CAssocShellElement
525{
526public:
527 /*** IPersist ***/
528 STDMETHODIMP GetClassID(CLSID* pClassID) override;
529
530 HRESULT _InitSource() override;
531};
532
533/******************************************************************************
534 * CAssocSystemExtElement
535 */
537 : public CAssocShellElement
538{
539public:
540 /*** IPersist ***/
541 STDMETHODIMP GetClassID(CLSID* pClassID) override;
542
543 HRESULT _InitSource() override;
544};
545
546/******************************************************************************
547 * CAssocFolderElement
548 */
550 : public CAssocShellElement
551{
552protected:
553
554public:
555 /*** IAssociationElementOld ***/
556 STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR* ppszValue) override;
557 /*** IPersist ***/
558 STDMETHODIMP GetClassID(CLSID* pClassID) override;
559
560 HRESULT _InitSource() override;
561};
562
563/******************************************************************************
564 * CAssocStarElement
565 */
567 : public CAssocShellElement
568{
569protected:
570
571public:
572 /*** IAssociationElementOld ***/
573 STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR* ppszValue) override;
574 /*** IPersist ***/
575 STDMETHODIMP GetClassID(CLSID* pClassID) override;
576
577 HRESULT _InitSource() override;
578};
579
580/******************************************************************************
581 * CAssocPerceivedElement
582 */
584 : public CAssocShellElement
585{
586protected:
588
589 UINT _GetQueryKeyVal(const QUERYKEYVAL** ppItems) override;
590
591public:
592 /*** IPersist ***/
593 STDMETHODIMP GetClassID(CLSID* pClassID) override;
594 /*** IObjectWithQuerySourceOld ***/
595 STDMETHODIMP GetSource(REFIID riid, PVOID* ppSource) override;
596
597 HRESULT _InitSource() override;
598 HRESULT _GetVerbDelegate(PCWSTR pszSrc, IAssociationElementOld** ppElement) override;
599};
600
601/******************************************************************************
602 * CAssocClientElement
603 */
605 : public CAssocShellElement
606{
607public:
608 /*** IAssociationElementOld ***/
609 STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR* ppszValue) override;
610 /*** IPersist ***/
611 STDMETHODIMP GetClassID(CLSID* pClassID) override;
612
613 HRESULT _InitSource() override;
617};
618
619/******************************************************************************
620 * CAssocElement methods
621 */
622
624{
625 if (m_pSource)
626 {
627 m_pSource->Release();
628 m_pSource = NULL;
629 }
630}
631
633{
634 *ppItems = NULL;
635 return 0;
636}
637
641 const QUERYKEYVAL* pItems,
642 UINT cItems,
643 IQuerySourceOld* pQS,
645 PCWSTR valueName,
647{
648 const QUERYKEYVAL* pItem = _FindKeyVal(query, pItems, cItems);
649 if (!pItem)
650 return E_INVALIDARG;
651
652 WCHAR szBuff[128];
653 PCWSTR key = pItem->key;
655 {
656 StringCchPrintfW(szBuff, _countof(szBuff), key, valueName);
657 key = szBuff;
658 }
659 return callback(pQS, query, key, pItem->value, pValue);
660}
661
665 IQuerySourceOld* pSource,
668 PCWSTR valueName,
670{
671 if (!pSource)
672 return E_INVALIDARG;
673
676 {
677 return callback(pSource, query, NULL, valueName, pValue);
678 }
679
680 if ((query & dwFlags) != dwFlags)
681 return E_INVALIDARG;
682
683 const QUERYKEYVAL* pItems = NULL;
684 UINT cItems = _GetQueryKeyVal(&pItems);
685 if (!cItems)
686 return E_INVALIDARG;
687
688 return _QueryKeyValAny(callback, pItems, cItems, pSource, query, valueName, pValue);
689}
690
692{
694 {
695 *ppv = static_cast<IObjectWithQuerySourceOld*>(this);
696 AddRef();
697 return S_OK;
698 }
699 if (riid == IID_IAssociationElementOld)
700 {
701 *ppv = static_cast<IAssociationElementOld*>(this);
702 AddRef();
703 return S_OK;
704 }
705 ERR("E_NOINTERFACE: %s\n", wine_dbgstr_guid(&riid));
706 *ppv = NULL;
707 return E_NOINTERFACE;
708}
709
710STDMETHODIMP_(ULONG) CAssocElement::AddRef()
711{
713}
714
715STDMETHODIMP_(ULONG) CAssocElement::Release()
716{
718 if (!refs)
719 delete this;
720 return refs;
721}
722
723STDMETHODIMP CAssocElement::SetSource(IQuerySourceOld* pSource)
724{
725 if (m_pSource)
726 return E_UNEXPECTED;
727 m_pSource = pSource;
728 m_pSource->AddRef();
729 return S_OK;
730}
731
733{
734 if (!m_pSource)
735 {
736 *ppSource = NULL;
737 return E_NOINTERFACE;
738 }
739 return m_pSource->QueryInterface(riid, ppSource);
740}
741
743{
744 *ppszValue = NULL;
746 query, key, ppszValue);
747}
748
750{
752 query, key, pdwValue);
753}
754
756{
758 query, key, NULL);
759}
760
762{
763 *ppBlob = NULL;
765}
766
768{
769 *ppvObj = NULL;
770 return E_NOTIMPL;
771}
772
773/******************************************************************************
774 * CAssocShellElement methods
775 */
776
778{
779 if (m_pszName && m_pszName != m_szBuff)
781}
782
784{
785 if (riid == IID_IPersist)
786 {
787 *ppv = static_cast<IPersist*>(this);
788 AddRef();
789 return S_OK;
790 }
791 if (riid == IID_IPersistString2)
792 {
793 *ppv = static_cast<IPersistString2*>(this);
794 AddRef();
795 return S_OK;
796 }
798}
799
800STDMETHODIMP_(ULONG) CAssocShellElement::AddRef()
801{
802 return CAssocElement::AddRef();
803}
804
805STDMETHODIMP_(ULONG) CAssocShellElement::Release()
806{
807 return CAssocElement::Release();
808}
809
811{
813}
814
816{
817 *ppItems = g_shellKeyVals;
818 return _countof(g_shellKeyVals);
819}
820
822{
823 return FALSE;
824}
825
827{
828 return FALSE;
829}
830
831HRESULT CAssocShellElement::_GetVerbDelegate(PCWSTR pszSrc, IAssociationElementOld** ppElement)
832{
833 if (!m_pSource)
834 return E_FAIL;
835
836 HRESULT hr;
837 IQuerySourceOld* pSource;
838 if (pszSrc)
839 hr = QSOpen2(m_pSource, L"shell", pszSrc, 0, &pSource);
840 else
841 hr = _DefaultVerbSource(&pSource);
842
844 return hr;
845
846 BOOL bAppSource = _IsAppSource();
847 auto pElement = new(std::nothrow) CAssocShellVerbElement(bAppSource);
848 if (!pElement)
849 {
850 ERR("E_OUTOFMEMORY\n");
851 pSource->Release();
852 return E_OUTOFMEMORY;
853 }
854
855 hr = pElement->SetSource(pSource);
856 *ppElement = static_cast<IAssociationElementOld*>(pElement);
857 pSource->Release();
858 return hr;
859}
860
862{
864 return CAssocElement::QueryString(query, key, ppszValue);
865
866 IAssociationElementOld* pDelegate;
867 HRESULT hr = _GetVerbDelegate(key, &pDelegate);
869 return hr;
870
871 hr = pDelegate->QueryString(query, NULL, ppszValue);
872 pDelegate->Release();
873 return hr;
874}
875
877{
879 return CAssocElement::QueryDword(query, key, pdwValue);
880
881 IAssociationElementOld* pDelegate;
882 HRESULT hr = _GetVerbDelegate(key, &pDelegate);
884 return hr;
885
886 hr = pDelegate->QueryDword(query, NULL, pdwValue);
887 pDelegate->Release();
888 return hr;
889}
890
892{
895
896 IAssociationElementOld* pDelegate;
897 HRESULT hr = _GetVerbDelegate(key, &pDelegate);
899 return hr;
900
901 hr = pDelegate->QueryExists(query, NULL);
902 pDelegate->Release();
903 return hr;
904}
905
908{
910 return CAssocElement::QueryDirect(query, key, ppBlob);
911
912 IAssociationElementOld* pDelegate;
913 HRESULT hr = _GetVerbDelegate(key, &pDelegate);
915 return hr;
916
917 hr = pDelegate->QueryDirect(query, NULL, ppBlob);
918 pDelegate->Release();
919 return hr;
920}
921
924{
926 {
927 *ppvObj = NULL;
928 return E_INVALIDARG;
929 }
930
931 IAssociationElementOld* pDelegate;
932 HRESULT hr = _GetVerbDelegate(key, &pDelegate);
934 return hr;
935
937 hr = pDelegate->QueryInterface(riid, ppvObj);
938 else
939 hr = pDelegate->QueryObject(query, NULL, riid, ppvObj);
940
941 pDelegate->Release();
942 return hr;
943}
944
946{
947 *pClassID = CLSID_AssocShellElement;
948 return S_OK;
949}
950
952{
953 if (m_pszName)
954 return E_UNEXPECTED;
955
956 UINT cchBuff, cchString = lstrlenW(psz);
957 PWSTR pszBuff;
958 if (cchString >= _countof(m_szBuff))
959 {
960 cchBuff = cchString + 1;
961 pszBuff = (PWSTR)LocalAlloc(LPTR, cchBuff * sizeof(WCHAR));
962 }
963 else
964 {
965 pszBuff = m_szBuff;
966 cchBuff = _countof(m_szBuff);
967 }
968
969 m_pszName = pszBuff;
970 if (!m_pszName)
971 return E_UNEXPECTED;
972
973 StringCchCopyW(pszBuff, cchBuff, psz);
974 return _InitSource();
975}
976
978{
979 return SHStrDupW(m_pszName, ppsz);
980}
981
983{
984 IQuerySourceOld* pShellSource;
985 HRESULT hr = m_pSource->OpenSource(L"shell", FALSE, &pShellSource);
987 return hr;
988
990 PCWSTR pszVerb = L"open";
991 if (SUCCEEDED(pShellSource->QueryValueString(NULL, NULL, &pszValue)))
992 pszVerb = pszValue;
993
994 hr = pShellSource->OpenSource(pszVerb, FALSE, ppSource);
996 {
997 if (pszValue)
998 {
999 INT nDelim = StrCSpnW(pszValue, L" ,");
1000 if (nDelim != lstrlenW(pszValue))
1001 {
1002 pszValue[nDelim] = UNICODE_NULL;
1003 hr = pShellSource->OpenSource(pszValue, FALSE, ppSource);
1004 }
1005 }
1006 else
1007 {
1008 IEnumString* pEnum;
1009 if (_UseEnumForDefaultVerb() && SUCCEEDED(pShellSource->EnumSources(&pEnum)))
1010 {
1011 PWSTR pszFirst = NULL;
1012 ULONG cFetched = 0;
1013 if (SUCCEEDED(pEnum->Next(1, &pszFirst, &cFetched)))
1014 {
1015 hr = pShellSource->OpenSource(pszFirst, FALSE, ppSource);
1016 CoTaskMemFree(pszFirst);
1017 }
1018 pEnum->Release();
1019 }
1020 }
1021 }
1022
1023 if (pszValue)
1025
1026 pShellSource->Release();
1027 return hr;
1028}
1029
1030/******************************************************************************
1031 * CAssocShellVerbElement methods
1032 */
1033
1035 : m_bAppSource(bAppSource)
1036{
1037}
1038
1041 PCWSTR key,
1042 PWSTR* ppwsz)
1043{
1045 if (SUCCEEDED(hr))
1046 return hr;
1047
1048 PWSTR psz;
1049 if (query == ASSOCQUERY_SEV_7)
1050 {
1052 if (SUCCEEDED(hr))
1053 hr = _ExeFromCmd(psz, ppwsz);
1054 if (psz)
1055 CoTaskMemFree(psz);
1056 return hr;
1057 }
1058
1060 {
1062 if (SUCCEEDED(hr))
1063 {
1064 PathStripPathW(psz);
1066 }
1067 *ppwsz = psz;
1068 return hr;
1069 }
1070
1072 return SHStrDupW(L"System", ppwsz);
1073
1075 {
1076 IAssociationElementOld* pElement;
1077 hr = _GetAppDelegate(IID_PPV_ARG(IAssociationElementOld, &pElement));
1078 if (SUCCEEDED(hr))
1079 {
1080 hr = pElement->QueryString(ASSOCQUERY_APPKEY_FRIENDLYAPPNAME, NULL, ppwsz);
1081 pElement->Release();
1082 }
1083 }
1084
1085 return hr;
1086}
1087
1089{
1090 *ppItems = g_shellVerbKeyVals;
1092}
1093
1095{
1096 PWSTR psz = NULL;
1099 return hr;
1100
1101 IPersistString2* pPS2;
1102 hr = AssocCreateElement(CLSID_AssocApplicationElement, IID_PPV_ARG(IPersistString2, &pPS2));
1103 if (SUCCEEDED(hr))
1104 {
1105 hr = pPS2->SetString(psz);
1106 if (SUCCEEDED(hr))
1107 hr = pPS2->QueryInterface(riid, ppv);
1108 pPS2->Release();
1109 }
1110
1111 if (psz)
1112 CoTaskMemFree(psz);
1113
1114 return hr;
1115}
1116
1119{
1121 return E_INVALIDARG;
1122 return _GetAppDelegate(riid, ppvObj);
1123}
1124
1125/******************************************************************************
1126 * CAssocApplicationElement methods
1127 */
1128
1130{
1131 *ppItems = g_shellAppKeyVals;
1133}
1134
1136{
1137 PWSTR pchFileName = PathFindFileNameW(m_pszName);
1138
1139 WCHAR szSubKey[MAX_PATH];
1140 _MakeApplicationsKey(pchFileName, szSubKey, _countof(szSubKey));
1141
1143 IID_PPV_ARG(IQuerySourceOld, &m_pSource));
1144 m_bHasDir = (pchFileName != m_pszName);
1146 return S_FALSE;
1147
1148 return hr;
1149}
1150
1152{
1153 *pClsid = CLSID_AssocApplicationElement;
1154 return S_OK;
1155}
1156
1159{
1163}
1164
1166{
1169 return _GetAppDisplayName(ppsz);
1170
1171 return hr;
1172}
1173
1175{
1176 PWSTR pszName;
1177 if (!m_bHasDir)
1178 {
1181 return hr;
1182 }
1183 else
1184 {
1185 pszName = m_pszName;
1186 }
1187
1188 WCHAR szData[MAX_PATH];
1189 DWORD cbData = sizeof(szData);
1191 HRESULT hr = SKGetValueW(flags, NULL, pszName, 0, szData, &cbData);
1193 {
1194 UINT cchData = MAX_PATH;
1195 if (SHGetFileDescriptionW(pszName, NULL, NULL, szData, &cchData))
1196 {
1197 INT cchName = lstrlenW(szData);
1198 UINT cbName = (cchName + 1) * sizeof(WCHAR);
1199 SKSetValueW(flags, NULL, pszName, REG_SZ, (PBYTE)szData, cbName);
1200 hr = S_OK;
1201 }
1202 }
1203
1204 if (SUCCEEDED(hr))
1205 hr = SHStrDupW(szData, ppsz);
1206
1207 if (!m_bHasDir)
1208 CoTaskMemFree(pszName);
1209
1210 return hr;
1211}
1212
1213/******************************************************************************
1214 * CAssocProgidElement methods
1215 */
1216
1218{
1219 if (m_pSource2)
1220 {
1221 m_pSource2->Release();
1222 m_pSource2 = NULL;
1223 }
1224}
1225
1227{
1229 if (SUCCEEDED(hr))
1230 return hr;
1231
1233 {
1236 m_pSource2,
1237 query,
1238 key,
1239 ppszValue);
1240 }
1241
1243 return m_pSource->QueryValueString(NULL, NULL, ppszValue);
1244
1245 return hr;
1246}
1247
1249{
1250 *pClassID = CLSID_AssocProgidElement;
1251 return S_OK;
1252}
1253
1255{
1256 return TRUE;
1257}
1258
1260{
1261 HRESULT hr = S_OK;
1262 PWSTR pszName;
1263
1264 if (*m_pszName == L'.')
1265 {
1268 goto Exit;
1269
1270 hr = m_pSource2->QueryValueString(NULL, NULL, &pszName);
1271 }
1272 else
1273 {
1274 pszName = m_pszName;
1275 }
1276
1277 if (SUCCEEDED(hr))
1278 {
1279 HKEY hKey = _OpenProgidKey(pszName);
1280 if (hKey)
1281 {
1284 }
1285 else
1286 {
1287 hr = E_UNEXPECTED;
1288 }
1289
1290 if (pszName != m_pszName)
1291 CoTaskMemFree(pszName);
1292 }
1293
1294Exit:
1296 {
1298 m_pSource2 = NULL;
1299 return S_FALSE;
1300 }
1301
1302 return hr;
1303}
1304
1305/******************************************************************************
1306 * CAssocClsidElement methods
1307 */
1308
1310{
1311 *pClassID = CLSID_AssocClsidElement;
1312 return S_OK;
1313}
1314
1316{
1318}
1319
1320/******************************************************************************
1321 * CAssocSystemExtElement methods
1322 */
1323
1325{
1326 *pClassID = CLSID_AssocSystemElement;
1327 return S_OK;
1328}
1329
1331{
1332 return _QuerySourceCreateFromKey2(HKEY_CLASSES_ROOT, L"SystemFileAssociations", m_pszName,
1333 &m_pSource);
1334}
1335
1336/******************************************************************************
1337 * CAssocFolderElement methods
1338 */
1339
1341{
1343 return _SHAllocLoadString(GetModuleHandleW(L"shlwapi.dll"), IDS_FOLDER, ppszValue);
1344 return CAssocShellElement::QueryString(query, key, ppszValue);
1345}
1346
1348{
1349 *pClassID = CLSID_AssocFolderElement;
1350 return S_OK;
1351}
1352
1354{
1356 IID_PPV_ARG(IQuerySourceOld, &m_pSource));
1357}
1358
1359/******************************************************************************
1360 * CAssocStarElement methods
1361 */
1362
1364{
1366 return _GetFileTypeName(m_pszName, ppszValue);
1367
1368 return CAssocShellElement::QueryString(query, key, ppszValue);
1369}
1370
1372{
1373 *pClassID = CLSID_AssocStarElement;
1374 return S_OK;
1375}
1376
1378{
1380 IID_PPV_ARG(IQuerySourceOld, &m_pSource));
1381}
1382
1383/******************************************************************************
1384 * CAssocPerceivedElement methods
1385 */
1386
1388{
1389 if (m_bPerceived)
1390 {
1391 *ppItems = g_perceivedKeyVals;
1393 }
1394 else
1395 {
1396 *ppItems = g_shellKeyVals;
1397 return _countof(g_shellKeyVals);
1398 }
1399}
1400
1402{
1403 *pClassID = CLSID_AssocPerceivedElement;
1404 return S_OK;
1405}
1406
1408{
1409 *ppSource = NULL;
1410 if (m_bPerceived)
1411 return E_FAIL;
1412
1413 return CAssocElement::GetSource(riid, ppSource);
1414}
1415
1417{
1420 PWSTR pszType;
1423 return hr;
1424
1426 hr = _QuerySourceCreateFromKey2(HKEY_CLASSES_ROOT, L"SystemFileAssociations", pszType,
1427 &m_pSource);
1428 CoTaskMemFree(pszType);
1429 return hr;
1430}
1431
1432HRESULT CAssocPerceivedElement::_GetVerbDelegate(PCWSTR pszSrc, IAssociationElementOld** ppElement)
1433{
1434 if (m_bPerceived)
1435 return E_FAIL;
1436
1437 return CAssocShellElement::_GetVerbDelegate(pszSrc, ppElement);
1438}
1439
1440/******************************************************************************
1441 * CAssocClientElement methods
1442 */
1443
1445{
1446 HRESULT hr;
1447
1449 {
1451 if (SUCCEEDED(hr))
1452 return hr;
1453
1454 IAssociationElementOld* pDelegate;
1455 HRESULT hr = _GetVerbDelegate(key, &pDelegate);
1457 return hr;
1458
1459 hr = pDelegate->QueryString(ASSOCQUERY_DELEGATE, L"open", ppszValue);
1460 pDelegate->Release();
1461 return hr;
1462 }
1463
1465 {
1466 hr = CAssocElement::QueryString(ASSOCQUERY_LOCALIZEDSTRING, L"LocalizedString", ppszValue);
1467 if (SUCCEEDED(hr))
1468 return hr;
1470 }
1471
1472 return CAssocShellElement::QueryString(query, key, ppszValue);
1473}
1474
1476{
1477 *pClassID = CLSID_AssocClientElement;
1478 return S_OK;
1479}
1480
1482{
1483 WCHAR szBuff[MAX_PATH];
1484 StringCchPrintfW(szBuff, _countof(szBuff), L"SOFTWARE\\Clients\\%s", m_pszName);
1485
1487 if (SUCCEEDED(hr))
1488 return hr;
1489 return _InitSourceFromKey(HKEY_LOCAL_MACHINE, szBuff, 0);
1490}
1491
1493{
1494 HKEY hKeyParent;
1495 LSTATUS error = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Clients\\Mail", 0, NULL, 0,
1496 KEY_ALL_ACCESS, NULL, &hKeyParent, NULL);
1497 if (error)
1498 return E_FAIL;
1499
1500 DWORD dwDisposition;
1501 HKEY hKey;
1502 error = RegCreateKeyExW(hKeyParent, L"Netscape Messenger", 0, NULL, REG_OPTION_VOLATILE,
1503 KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
1504 if (error)
1505 {
1506 SHDeleteKeyW(hKeyParent, L"Netscape Messenger");
1507 RegCloseKey(hKeyParent);
1508 return E_FAIL;
1509 }
1510
1511 HRESULT hr = E_FAIL;
1513 {
1514 IQuerySourceOld* pNewSource = NULL;
1515 hr = _QuerySourceCreateFromKey(hKey, NULL, NULL, &pNewSource);
1516 if (SUCCEEDED(hr))
1517 {
1518 if (m_pSource)
1519 m_pSource->Release();
1520 m_pSource = pNewSource;
1521 }
1522 }
1523
1525
1527 SHDeleteKeyW(hKeyParent, L"Netscape Messenger");
1528
1529 RegCloseKey(hKeyParent);
1530 return hr;
1531}
1532
1534{
1535 HKEY hkResult;
1537 L"Software\\Clients\\Mail\\Netscape Messenger",
1538 0, KEY_READ, &hkResult);
1539 if (error)
1540 return FALSE;
1541
1542 WCHAR szIconFile[MAX_PATH];
1543 error = _RegQueryString(hkResult, L"Protocols\\mailto\\DefaultIcon",
1544 szIconFile, _countof(szIconFile));
1545 if (error == ERROR_SUCCESS)
1546 {
1547 PathParseIconLocationW(szIconFile);
1548 StringCchCatW(szIconFile, _countof(szIconFile), L",-1349");
1549 _RegSetVolatileString(hKey, L"DefaultIcon", szIconFile);
1550 }
1551
1552 BOOL ret = FALSE;
1553 PWSTR lpString2 = NULL;
1554 if (_RegQueryString(hkResult, 0, szIconFile, _countof(szIconFile)) == ERROR_SUCCESS &&
1555 _RegSetVolatileString(hKey, 0, szIconFile) == ERROR_SUCCESS &&
1556 _RegQueryString(hkResult, L"Protocols\\mailto\\shell\\open\\command",
1557 szIconFile, _countof(szIconFile)) == ERROR_SUCCESS &&
1558 SUCCEEDED(_ExeFromCmd(szIconFile, &lpString2)))
1559 {
1560 StringCchCopyW(szIconFile, _countof(szIconFile), lpString2);
1561 CoTaskMemFree(lpString2);
1562 PathQuoteSpacesW(szIconFile);
1563 StringCchCatW(szIconFile, _countof(szIconFile), L" -mail");
1564 if (_RegSetVolatileString(hKey, L"shell\\open\\command", szIconFile) == ERROR_SUCCESS)
1565 ret = TRUE;
1566 }
1567
1568 RegCloseKey(hkResult);
1569 return ret;
1570}
1571
1573{
1574 HKEY hKey2;
1575 LSTATUS error = RegOpenKeyExW(hKey, lpSubKey, 0, KEY_READ | dwFlags, &hKey2);
1576 if (error)
1577 return E_INVALIDARG;
1578
1580 HKEY hkeySrc = NULL;
1581 WCHAR szData[80];
1582 DWORD dwType, cbData = sizeof(szData);
1583 error = RegQueryValueExW(hKey2, NULL, NULL, &dwType, (PBYTE)szData, &cbData);
1584 if (error == ERROR_SUCCESS && dwType == REG_SZ && szData[0] &&
1585 RegOpenKeyExW(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hkeySrc) == ERROR_SUCCESS)
1586 {
1587 hr = _QuerySourceCreateFromKey2(hkeySrc, NULL, szData, &m_pSource);
1588 RegCloseKey(hkeySrc);
1589 }
1590
1591 RegCloseKey(hKey2);
1592
1593 if (FAILED_UNEXPECTEDLY(hr) ||
1594 lstrcmpiW(m_pszName, L"mail") != 0 ||
1595 lstrcmpiW(szData, L"Netscape Messenger") != 0 ||
1597 {
1598 return hr;
1599 }
1600
1601 return _FixNetscapeRegistration();
1602}
1603
1604/******************************************************************************
1605 * AssocCreateElement [SHELL32.764] (Vista+)
1606 * AssocCreateElement [SHLWAPI internal] (XP)
1607 *
1608 * @see AssocCreate
1609 * @see https://www.geoffchappell.com/studies/windows/shell/shell32/api/assocelem/createelement.htm
1610 */
1613{
1614 IAssociationElementOld* pElement;
1615 if (rclsid == CLSID_AssocShellElement)
1616 {
1617 auto pNewElement = new(std::nothrow) CAssocShellElement();
1618 pElement = static_cast<IAssociationElementOld*>(pNewElement);
1619 }
1620 else if (rclsid == CLSID_AssocApplicationElement)
1621 {
1622 auto pNewElement = new(std::nothrow) CAssocApplicationElement();
1623 pElement = static_cast<IAssociationElementOld*>(pNewElement);
1624 }
1625 else if (rclsid == CLSID_AssocProgidElement)
1626 {
1627 auto pNewElement = new(std::nothrow) CAssocProgidElement();
1628 pElement = static_cast<IAssociationElementOld*>(pNewElement);
1629 }
1630 else if (rclsid == CLSID_AssocClsidElement)
1631 {
1632 auto pNewElement = new(std::nothrow) CAssocClsidElement();
1633 pElement = static_cast<IAssociationElementOld*>(pNewElement);
1634 }
1635 else if (rclsid == CLSID_AssocSystemElement)
1636 {
1637 auto pNewElement = new(std::nothrow) CAssocSystemExtElement();
1638 pElement = static_cast<IAssociationElementOld*>(pNewElement);
1639 }
1640 else if (rclsid == CLSID_AssocFolderElement)
1641 {
1642 auto pNewElement = new(std::nothrow) CAssocFolderElement();
1643 pElement = static_cast<IAssociationElementOld*>(pNewElement);
1644 }
1645 else if (rclsid == CLSID_AssocStarElement)
1646 {
1647 auto pNewElement = new(std::nothrow) CAssocStarElement();
1648 pElement = static_cast<IAssociationElementOld*>(pNewElement);
1649 }
1650 else if (rclsid == CLSID_AssocPerceivedElement)
1651 {
1652 auto pNewElement = new(std::nothrow) CAssocPerceivedElement();
1653 pElement = static_cast<IAssociationElementOld*>(pNewElement);
1654 }
1655 else if (rclsid == CLSID_AssocClientElement)
1656 {
1657 auto pNewElement = new(std::nothrow) CAssocClientElement();
1658 pElement = static_cast<IAssociationElementOld*>(pNewElement);
1659 }
1660 else
1661 {
1662 ERR("rclsid: %s\n", wine_dbgstr_guid(&rclsid));
1663 *ppvObj = NULL;
1665 }
1666
1667 if (!pElement)
1668 {
1669 ERR("E_OUTOFMEMORY\n");
1670 return E_OUTOFMEMORY;
1671 }
1672
1673 HRESULT hr = pElement->QueryInterface(riid, ppvObj);
1674 pElement->Release();
1675 return hr;
1676}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ERR(fmt,...)
Definition: precomp.h:57
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHODIMP
Definition: basetyps.h:43
#define STDMETHODIMP_(t)
Definition: basetyps.h:44
#define RegCloseKey(hKey)
Definition: registry.h:49
_In_ BOOLEAN Release
Definition: cdrom.h:920
HINSTANCE hInstance
Definition: charmap.c:19
HRESULT _InitSource() override
Definition: elements.cpp:1135
HRESULT _GetAppDisplayName(PWSTR *ppsz)
Definition: elements.cpp:1174
UINT _GetQueryKeyVal(const QUERYKEYVAL **ppItems) override
Definition: elements.cpp:1129
STDMETHODIMP GetClassID(CLSID *pClsid) override
Definition: elements.cpp:1151
STDMETHODIMP QueryObject(ASSOCQUERY query, PCWSTR key, REFIID riid, PVOID *ppv) override
Definition: elements.cpp:1158
STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR *ppsz) override
Definition: elements.cpp:1165
HRESULT _InitSourceFromKey(HKEY hKey, PCWSTR lpSubKey, DWORD dwFlags)
Definition: elements.cpp:1572
STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) override
Definition: elements.cpp:1444
HRESULT _FixNetscapeRegistration()
Definition: elements.cpp:1492
HRESULT _InitSource() override
Definition: elements.cpp:1481
STDMETHODIMP GetClassID(CLSID *pClassID) override
Definition: elements.cpp:1475
BOOL _CreateRepairedNetscapeRegistration(HKEY hKey)
Definition: elements.cpp:1533
HRESULT _InitSource() override
Definition: elements.cpp:1315
STDMETHODIMP GetClassID(CLSID *pClassID) override
Definition: elements.cpp:1309
STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv) override
Definition: elements.cpp:691
STDMETHODIMP QueryObject(ASSOCQUERY query, PCWSTR key, REFIID riid, PVOID *ppvObj) override
Definition: elements.cpp:767
virtual ~CAssocElement()
Definition: elements.cpp:623
STDMETHODIMP SetSource(IQuerySourceOld *pSource) override
Definition: elements.cpp:723
STDMETHODIMP QueryDirect(ASSOCQUERY query, PCWSTR key, FLAGGED_BYTE_BLOB **ppBlob) override
Definition: elements.cpp:761
STDMETHODIMP QueryExists(ASSOCQUERY query, PCWSTR key) override
Definition: elements.cpp:755
IQuerySourceOld * m_pSource
Definition: elements.cpp:383
HRESULT _QueryKeyValAny(QUERY_CALLBACK callback, const QUERYKEYVAL *pItems, UINT cItems, IQuerySourceOld *pQS, ASSOCQUERY query, PCWSTR valueName, PVOID pValue)
Definition: elements.cpp:639
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP_(ULONG) Release() override
STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) override
Definition: elements.cpp:742
STDMETHODIMP QueryDword(ASSOCQUERY query, PCWSTR key, DWORD *pdwValue) override
Definition: elements.cpp:749
HRESULT _QuerySourceAny(QUERY_CALLBACK callback, IQuerySourceOld *pSource, DWORD dwFlags, ASSOCQUERY query, PCWSTR valueName, PVOID pValue)
Definition: elements.cpp:663
virtual UINT _GetQueryKeyVal(const QUERYKEYVAL **ppItems)
Definition: elements.cpp:632
STDMETHODIMP GetSource(REFIID riid, PVOID *ppSource) override
Definition: elements.cpp:732
HRESULT _InitSource() override
Definition: elements.cpp:1353
STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) override
Definition: elements.cpp:1340
STDMETHODIMP GetClassID(CLSID *pClassID) override
Definition: elements.cpp:1347
UINT _GetQueryKeyVal(const QUERYKEYVAL **ppItems) override
Definition: elements.cpp:1387
HRESULT _GetVerbDelegate(PCWSTR pszSrc, IAssociationElementOld **ppElement) override
Definition: elements.cpp:1432
HRESULT _InitSource() override
Definition: elements.cpp:1416
STDMETHODIMP GetSource(REFIID riid, PVOID *ppSource) override
Definition: elements.cpp:1407
STDMETHODIMP GetClassID(CLSID *pClassID) override
Definition: elements.cpp:1401
HRESULT _InitSource() override
Definition: elements.cpp:1259
STDMETHODIMP GetClassID(CLSID *pClassID) override
Definition: elements.cpp:1248
BOOL _UseEnumForDefaultVerb() override
Definition: elements.cpp:1254
STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) override
Definition: elements.cpp:1226
IQuerySourceOld * m_pSource2
Definition: elements.cpp:506
~CAssocProgidElement() override
Definition: elements.cpp:1217
WCHAR m_szBuff[64]
Definition: elements.cpp:432
STDMETHODIMP QueryObject(ASSOCQUERY query, PCWSTR key, REFIID riid, PVOID *ppvObj) override
Definition: elements.cpp:923
STDMETHODIMP SetString(PCWSTR psz) override
Definition: elements.cpp:951
STDMETHODIMP GetClassID(CLSID *pClassID) override
Definition: elements.cpp:945
virtual BOOL _IsAppSource()
Definition: elements.cpp:826
STDMETHODIMP QueryDword(ASSOCQUERY query, PCWSTR key, DWORD *pdwValue) override
Definition: elements.cpp:876
STDMETHODIMP GetString(PWSTR *ppsz) override
Definition: elements.cpp:977
virtual HRESULT _InitSource()
Definition: elements.cpp:810
UINT _GetQueryKeyVal(const QUERYKEYVAL **ppItems) override
Definition: elements.cpp:815
STDMETHODIMP_(ULONG) AddRef() override
virtual BOOL _UseEnumForDefaultVerb()
Definition: elements.cpp:821
STDMETHODIMP QueryExists(ASSOCQUERY query, PCWSTR key) override
Definition: elements.cpp:891
STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv) override
Definition: elements.cpp:783
STDMETHODIMP QueryDirect(ASSOCQUERY query, PCWSTR key, FLAGGED_BYTE_BLOB **ppBlob) override
Definition: elements.cpp:907
HRESULT _DefaultVerbSource(IQuerySourceOld **ppSource)
Definition: elements.cpp:982
virtual HRESULT _GetVerbDelegate(PCWSTR pszSrc, IAssociationElementOld **ppElement)
Definition: elements.cpp:831
STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) override
Definition: elements.cpp:861
STDMETHODIMP_(ULONG) Release() override
UINT _GetQueryKeyVal(const QUERYKEYVAL **ppItems) override
Definition: elements.cpp:1088
CAssocShellVerbElement(BOOL bAppSource)
Definition: elements.cpp:1034
STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR *ppwsz) override
Definition: elements.cpp:1039
STDMETHODIMP QueryObject(ASSOCQUERY query, PCWSTR key, REFIID riid, PVOID *ppvObj) override
Definition: elements.cpp:1118
HRESULT _GetAppDelegate(REFIID riid, PVOID *ppv)
Definition: elements.cpp:1094
STDMETHODIMP QueryString(ASSOCQUERY query, PCWSTR key, PWSTR *ppszValue) override
Definition: elements.cpp:1363
STDMETHODIMP GetClassID(CLSID *pClassID) override
Definition: elements.cpp:1371
HRESULT _InitSource() override
Definition: elements.cpp:1377
HRESULT _InitSource() override
Definition: elements.cpp:1330
STDMETHODIMP GetClassID(CLSID *pClassID) override
Definition: elements.cpp:1324
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
_Check_return_ _In_ PQUERY_INTERFACE QueryInterface
Definition: dispmprt.h:1318
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LSTATUS WINAPI RegQueryValueW(HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count)
Definition: reg.c:4241
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
int WINAPI StrCSpnW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
Definition: string.c:839
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:500
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define lstrlenW
Definition: compat.h:750
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
void WINAPI PathRemoveExtensionW(WCHAR *path)
Definition: path.c:1922
void WINAPI PathUnquoteSpacesW(WCHAR *path)
Definition: path.c:1982
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1677
void WINAPI PathStripPathW(WCHAR *path)
Definition: path.c:2304
int WINAPI PathParseIconLocationW(WCHAR *path)
Definition: path.c:2620
HRESULT WINAPI PathCchAddExtension(WCHAR *path, SIZE_T size, const WCHAR *extension)
Definition: path.c:542
BOOL WINAPI PathFileExistsW(const WCHAR *path)
Definition: path.c:2583
BOOL WINAPI PathIsFileSpecW(const WCHAR *path)
Definition: path.c:1818
HRESULT WINAPI PathCchCombineEx(WCHAR *out, SIZE_T size, const WCHAR *path1, const WCHAR *path2, DWORD flags)
Definition: path.c:674
void WINAPI PathQuoteSpacesW(WCHAR *path)
Definition: path.c:2520
LPWSTR WINAPI CharUpperW(WCHAR *str)
Definition: string.c:1249
HRESULT WINAPI SHLoadIndirectString(const WCHAR *src, WCHAR *dst, UINT dst_len, void **reserved)
Definition: string.c:1499
int WINAPI StrCmpIW(const WCHAR *str, const WCHAR *comp)
Definition: string.c:464
HRESULT WINAPI SHStrDupW(const WCHAR *src, WCHAR **dest)
Definition: main.c:1692
DWORD WINAPI SHGetValueW(HKEY hkey, const WCHAR *subkey, const WCHAR *value, DWORD *type, void *data, DWORD *data_len)
Definition: main.c:2222
DWORD WINAPI SHDeleteKeyW(HKEY hkey, const WCHAR *subkey)
Definition: main.c:1886
#define IDS_ANY_FILE
Definition: resource.h:5
#define IDS_FOLDER
Definition: resource.h:7
#define IDS_FILE
Definition: resource.h:6
HRESULT WINAPI AssocGetPerceivedType(LPCWSTR lpszExt, PERCEIVED *lpType, INT *lpFlag, LPWSTR *lppszType)
Definition: assoc.c:433
HRESULT WINAPI SKGetValueW(DWORD flags, LPCWSTR subkey, LPCWSTR value, DWORD *type, void *data, DWORD *count)
Definition: ordinal.c:4311
HRESULT WINAPI SKSetValueW(DWORD flags, LPCWSTR subkey, LPCWSTR value, DWORD type, void *data, DWORD count)
Definition: ordinal.c:4333
BOOL WINAPI PathFileExistsAndAttributesW(LPCWSTR lpszPath, DWORD *dwAttr)
Definition: path.c:747
BOOL WINAPI SHGetFileDescriptionW(_In_ PCWSTR pszPath, _In_opt_ PCWSTR pszVerKey, _In_opt_ PCWSTR pszDisplayName, _Out_opt_ PWSTR pszOut, _Inout_ PUINT pcchOut)
Definition: utils.cpp:1087
#define FAILED_UNEXPECTEDLY
Definition: utils.cpp:33
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
static HRESULT _AssocOpenRegKey(HKEY hKey, PCWSTR lpSubKey, PHKEY phkResult, BOOL bCreate)
Definition: elements.cpp:229
static HRESULT _GetFileTypeName(PWSTR lpsz, PWSTR *ppwsz)
Definition: elements.cpp:118
static LSTATUS _RegQueryString(HKEY hKey, PCWSTR lpSubKey, PWSTR lpData, LONG cchData)
Definition: elements.cpp:133
static const QUERYKEYVAL g_shellVerbKeyVals[]
Definition: elements.cpp:52
static HRESULT CALLBACK _QuerySourceString(IQuerySourceOld *pSource, ASSOCQUERY query, PCWSTR keyName, PCWSTR valueName, PVOID pValue)
Definition: elements.cpp:191
static HRESULT _QuerySourceCreateFromKey(HKEY hKey, PCWSTR lpSubKey, BOOL bCreate, IQuerySourceOld **ppSource)
Definition: elements.cpp:205
struct QUERYKEYVAL * PQUERYKEYVAL
static const QUERYKEYVAL g_progidKeyVals[2]
Definition: elements.cpp:69
static void _MakeApplicationsKey(PCWSTR pszPath, PWSTR pszDest, UINT cchDest)
Definition: elements.cpp:290
static LSTATUS _RegSetVolatileString(HKEY hKey, PCWSTR lpSubKey, PCWSTR lpString)
Definition: elements.cpp:140
static HRESULT CALLBACK _QuerySourceExists(IQuerySourceOld *pSource, ASSOCQUERY query, PCWSTR keyName, PCWSTR valueName, PVOID pValue)
Definition: elements.cpp:180
HRESULT(CALLBACK * QUERY_CALLBACK)(IQuerySourceOld *, ASSOCQUERY query, PCWSTR keyName, PCWSTR valueName, PVOID pValue)
Definition: elements.cpp:27
static HRESULT CALLBACK _QuerySourceDirect(IQuerySourceOld *pSource, ASSOCQUERY query, PCWSTR keyName, PCWSTR valueName, PVOID pValue)
Definition: elements.cpp:158
static BOOL _ParamIsApp(PCWSTR psz)
Definition: elements.cpp:299
static const QUERYKEYVAL g_perceivedKeyVals[]
Definition: elements.cpp:37
static HRESULT SHAllocMUI(PWSTR *ppwsz)
Definition: elements.cpp:86
static HKEY _OpenProgidKey(PCWSTR psz)
Definition: elements.cpp:248
static const QUERYKEYVAL g_shellAppKeyVals[]
Definition: elements.cpp:64
static HRESULT _SHAllocLoadString(HINSTANCE hInstance, UINT uID, PWSTR *ppwsz)
Definition: elements.cpp:99
EXTERN_C HRESULT WINAPI AssocCreateElement(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ PVOID *ppvObj)
Definition: elements.cpp:1612
static HRESULT QSOpen2(IQuerySourceOld *pSource, PCWSTR key, PCWSTR pszSrc, BOOL bCreate, IQuerySourceOld **ppSource)
Definition: elements.cpp:106
static const QUERYKEYVAL * _FindKeyVal(ASSOCQUERY query, const QUERYKEYVAL *pItems, UINT cItems)
Definition: elements.cpp:76
static HRESULT _QuerySourceCreateFromKey2(HKEY hKey, PCWSTR key1, PCWSTR key2, IQuerySourceOld **ppSource)
Definition: elements.cpp:212
static HRESULT CALLBACK _QuerySourceDword(IQuerySourceOld *pSource, ASSOCQUERY query, PCWSTR keyName, PCWSTR valueName, PVOID pValue)
Definition: elements.cpp:169
static HRESULT _PathFileExists(PCWSTR lpFileName)
Definition: elements.cpp:304
static const QUERYKEYVAL g_shellKeyVals[]
Definition: elements.cpp:43
static HRESULT _ExeFromCmd(PCWSTR pszCmdTemplate, PWSTR *ppszApplication)
Definition: elements.cpp:312
#define ASSOCQUERY_DELEGATE
Definition: elements.h:34
#define ASSOCQUERY_CONTENT_TYPE
Definition: elements.h:33
#define ASSOCQUERY_CLSID
Definition: elements.h:18
#define ASSOCQUERY_COMMAND_COMMAND
Definition: elements.h:22
#define ASSOCQUERY_DDEEXEC
Definition: elements.h:26
#define ASSOCQUERY_SEV_7
Definition: elements.h:31
#define ASSOCQUERY_SHELLEX
Definition: elements.h:20
#define ASSOCQUERY_DDEEXEC_TOPIC
Definition: elements.h:29
#define ASSOCQUERY_VERB_FRIENDLYAPPNAME
Definition: elements.h:24
#define ASSOCQUERY_DDEEXEC_IFEXEC
Definition: elements.h:27
#define ASSOCQUERY_LOCALIZEDSTRING
Definition: elements.h:30
#define ASSOCQUERY_FRIENDLYAPPNAME
Definition: elements.h:23
#define ASSOCQUERY_DEFAULTICON
Definition: elements.h:17
#define ASSOCQUERY_PROGID
Definition: elements.h:19
#define ASSOCQUERY_OBJECT_EV_1
Definition: elements.h:35
#define ASSOCQUERY_APPKEY_FRIENDLYAPPNAME
Definition: elements.h:32
#define ASSOCQUERY_DDEEXEC_APPLICATION
Definition: elements.h:28
#define ASSOCQUERY_NOACTIVATEHANDLER
Definition: elements.h:21
#define ASSOCQUERY_COMMAND
Definition: elements.h:25
#define ASSOCQUERY_SDED
Definition: elements.h:13
EXTERN_C HRESULT _PathCopyExeAndTrimWhiteSpaces(PWSTR pszBuff, size_t cchBuff, PCWSTR pszSrc, size_t cchSrc)
Definition: evalcmd.cpp:53
EXTERN_C HRESULT _PathFindInSystem(_Inout_ PWSTR pszPath, _In_ UINT cchPath)
Definition: evalcmd.cpp:162
EXTERN_C HRESULT WINAPI SHEvaluateSystemCommandTemplate(_In_ PCWSTR pszCmdTemplate, _Outptr_ PWSTR *ppszApplication, _Outptr_opt_ PWSTR *ppszCommandLine, _Outptr_opt_ PWSTR *ppszParameters)
Definition: evalcmd.cpp:182
#define SHELL32_CAssocElement_Version
Definition: evalcmd.h:23
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
PWCHAR pValue
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
Definition: glext.h:10608
unsigned int UINT
Definition: sysinfo.c:13
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] LPOLESTR *rgelt, [out] ULONG *pceltFetched)
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define C_ASSERT(e)
Definition: intsafe.h:73
#define REG_SZ
Definition: layer.c:22
#define LPTR
Definition: minwinbase.h:93
#define error(str)
Definition: mkdosfs.c:1605
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static IPrintDialogCallback callback
Definition: printdlg.c:326
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:83
@ SHKEY_Key_ShellNoRoam
Definition: ordinal.c:2809
@ SHKEY_Subkey_MUICache
Definition: ordinal.c:2816
@ SHKEY_Root_HKCU
Definition: ordinal.c:2805
static int int const SCRIPT_CONTROL const SCRIPT_STATE SCRIPT_ITEM * pItems
Definition: usp10.c:62
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _Outptr_
Definition: no_sal2.h:262
#define _In_
Definition: no_sal2.h:158
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define KEY_READ
Definition: nt_native.h:1026
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define KEY_WRITE
Definition: nt_native.h:1034
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1088
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1063
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define UNICODE_NULL
@ PATHCCH_NONE
Definition: pathcch.h:39
BYTE * PBYTE
Definition: pedump.c:66
short WCHAR
Definition: pedump.c:58
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
const GUID IID_IPersist
Definition: proxy.cpp:14
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
_In_ INT cchDest
Definition: shlwapi.h:1161
INT PERCEIVEDFLAG
Definition: shlwapi.h:1002
_In_ UINT uID
Definition: shlwapi.h:156
_In_opt_ LPCSTR _In_opt_ LPCSTR pszValue
Definition: shlwapi.h:783
#define PERCEIVEDFLAG_NATIVESUPPORT
Definition: shtypes.idl:188
EXTERN_C HRESULT WINAPI QuerySourceCreateFromKey(_In_ HKEY hKey, _In_opt_ PCWSTR lpSubKey, _In_ BOOL bCreate, _In_ REFIID riid, _Outptr_ PVOID *ppv)
Definition: querysrc.cpp:577
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:171
#define LoadStringW
Definition: utils.h:64
#define _WIN32_WINNT_WINXP
Definition: sdkddkver.h:22
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
#define IID_IObjectWithQuerySourceOld
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1536
#define ASSOCQUERY_DWORD
Definition: shlobj_undoc.h:38
DWORD ASSOCQUERY
Definition: shlobj_undoc.h:33
#define ASSOCQUERY_DIRECT
Definition: shlobj_undoc.h:37
#define ASSOCQUERY_STRING
Definition: shlobj_undoc.h:35
#define ASSOCQUERY_INDIRECT
Definition: shlobj_undoc.h:39
#define ASSOCQUERY_EXTRA_VERB
Definition: shlobj_undoc.h:43
#define ASSOCQUERY_EXTRA_NON_VERB
Definition: shlobj_undoc.h:42
#define ASSOCQUERY_FALLBACK
Definition: shlobj_undoc.h:45
#define ASSOCQUERY_OBJECT
Definition: shlobj_undoc.h:40
static BOOL PathIsAbsolute(_In_ PCWSTR pszPath)
enum tagPERCEIVED PERCEIVED
#define _countof(array)
Definition: sndvol32.h:70
static void Exit(void)
Definition: sock.c:1330
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
ASSOCQUERY query
Definition: elements.cpp:32
PCWSTR value
Definition: elements.cpp:34
PCWSTR key
Definition: elements.cpp:33
Definition: copy.c:22
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
_In_ LPCSTR lpFileName
Definition: winbase.h:2800
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2497
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define ERROR_NO_ASSOCIATION
Definition: winerror.h:1001
#define E_UNEXPECTED
Definition: winerror.h:3528
#define CLASS_E_CLASSNOTAVAILABLE
Definition: winerror.h:3772
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define IID_PPV_ARG(Itype, ppType)