ReactOS 0.4.17-dev-683-g0dafdc5
CQueryAssociations.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: IQueryAssociations
5 * COPYRIGHT: Copyright 2002 Jon Griffiths (Wine)
6 * Copyright 2024-2026 Whindmar Saksit <whindsaks@proton.me>
7 */
8
9#include "precomp.h"
10#include <shlwapi_undoc.h> // AssocCreateElement
11#include "evalcmd/elements.h" // ASSOCQUERY_*
12#include <evalcmd.h> // SHELL32_CAssocElement_Version
13#if NTDDI_VERSION < NTDDI_WIN10_RS1
14#define ASSOCF_PER_MACHINE_ONLY 0x00008000
15#endif
16
18
19static inline HRESULT SHRegDuplicateHKey(HKEY hKey, HKEY *phKey)
20{
21 hKey = *phKey = ::SHRegDuplicateHKey(hKey);
23}
24
26{
27#if DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA
28 return AssocCreateElement(rclsid, riid, ppv);
29#else
30 return AssocCreate(rclsid, riid, ppv);
31#endif
32}
33
34static HRESULT AssocCreateElementInternal(REFCLSID rclsid, IQuerySource *pQS, REFIID riid, PVOID *ppv)
35{
36 HRESULT hr;
37 C_ASSERT(&IID_IObjectWithQuerySource == &IID_IObjectWithQuerySourceOld);
39 if (FAILED(hr = SH32_AssocCreateElement(rclsid, IID_PPV_ARG(IObjectWithQuerySource, &pOWQS))))
40 return hr;
41 return (SUCCEEDED(hr = pOWQS->SetSource(pQS))) ? pOWQS->QueryInterface(riid, ppv) : hr;
42}
43
46{
48 REFIID riidQS = Major > 5 ? IID_IQuerySource : IID_IQuerySourceOld;
49 HRESULT hr = QuerySourceCreateFromKey(hKey, pszSubKey, false, riidQS, (void**)&pQSO);
50 if (FAILED(hr))
51 return hr;
52 return AssocCreateElementInternal(rclsid, (IQuerySource*)static_cast<IUnknown*>(pQSO), riid, ppv);
53}
54
57{
58#if DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA
60 if (SUCCEEDED(hr))
61 return hr;
62#endif
64}
65
67 _In_opt_ PCWSTR pszSubKey, _In_ PCWSTR pszExtra, _Out_ PWSTR *ppszValue)
68{
69#if SHELL32_CAssocElement_Version >= _WIN32_WINNT_VISTA
71 REFIID riid = IID_IAssociationElement;
72#else
74 REFIID riid = IID_IAssociationElementOld;
75#endif
76 HRESULT hr = SH32_AssocCreateElementOnKey(rclsid, hKey, pszSubKey, riid, (void**)&pAE);
77 if (FAILED(hr))
78 return hr;
79 return pAE->QueryString(Query, pszExtra, ppszValue);
80}
81
82template<class T> static HRESULT GetKeyFromObjectWithQuerySource(T &Obj, HKEY *phKey)
83{
84 HRESULT hr;
85 C_ASSERT(&IID_IObjectWithQuerySource == &IID_IObjectWithQuerySourceOld);
87 if (FAILED(hr = Obj.QueryInterface(IID_PPV_ARG(IObjectWithQuerySource, &pOWQS))))
88 return hr;
91 if (SUCCEEDED(hr = pOWQS->GetSource(IID_PPV_ARG(IObjectWithRegistryKeyOld, &pOWRKO))))
92 hr = pOWRKO->GetKey(phKey);
93#if DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA
94 else if (SUCCEEDED(hr = pOWQS->GetSource(IID_PPV_ARG(IObjectWithRegistryKey, &pOWRK))))
95 hr = pOWRK->GetKey(MAXIMUM_ALLOWED, phKey);
96#endif
97 return hr;
98}
99
101{
102 static WCHAR cache[33] = {};
103 if (!*cache)
105 return StringCchCopyW(Buf, cchBuf, cache);
106}
107
109{
110 static WCHAR fmt[33] = {};
111 if (!*fmt)
113 return StringCchPrintfW(Buf, cchBuf, fmt, DotExt);
114}
115
117{
118 HRESULT hr;
119 if (!DotExt[0] || (!DotExt[1] && DotExt[0] == '.'))
120 {
122 StrTrimW(Buf, L" -"); // Remove the empty %s so we are left with "File"
123 return hr;
124 }
125 HKEY hKey;
127 {
128 DWORD err = RegLoadMUIStringW(hKey, L"FriendlyTypeName", Buf, cchBuf, NULL, 0, NULL);
129 if (err && hr == S_OK) // ProgId default value fallback (but not if we only have a .ext key)
130 {
131 DWORD cb = cchBuf * sizeof(*Buf);
133 }
135 if (!err)
136 return err;
137 }
138 // No information in the registry, default to "UPPERCASEEXT File"
139 WCHAR ext[MAX_PATH + 33];
141 DotExt = ext;
142 return GetExtensionDefaultDescription(DotExt, Buf, cchBuf);
143}
144
146{
148}
149
151{
152 HRESULT Initialize(ASSOCF fA, PCWSTR pszSource);
153};
154
156{
157 if (!(fA & ASSOCF_PER_MACHINE_ONLY))
158 {
160 return S_OK;
161 }
162 HKEY hKeyClasses;
163 LONG err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Classes", 0, KEY_READ, &hKeyClasses);
164 if (err)
165 return HResultFromWin32(err);
166 err = RegOpenKeyExW(hKeyClasses, pszSource, 0, KEY_READ, &hKey);
167 RegCloseKey(hKeyClasses);
168 if (err == ERROR_SUCCESS)
169 hKeyClose = hKey;
170 return HResultFromWin32(err);
171}
172
173static HRESULT OpenShellVerbKey(HKEY hClass, LPCWSTR pszVerb, HKEY *phKey)
174{
175 const SIZE_T cchPrefix = sizeof("shell\\") - 1;
176 WCHAR szPath[cchPrefix + MAX_PATH];
177 if (FAILED(StringCchPrintfW(szPath, _countof(szPath), L"shell\\%s", pszVerb ? pszVerb : L"")))
178 return E_FAIL;
179
180 if (!pszVerb && !HCR_GetDefaultVerbW(hClass, NULL, szPath + cchPrefix, _countof(szPath) - cchPrefix))
182
183 return HResultFromWin32(RegOpenKeyExW(hClass, szPath, 0, KEY_READ, phKey));
184}
185
186static HRESULT OpenClassWithShellExecKey(ASSOCF fA, HKEY hClass, LPCWSTR pszVerb, HKEY *phKey)
187{
188 if (fA & ASSOCF_VERIFY)
189 {
190 HRESULT hr = OpenShellVerbKey(hClass, pszVerb, phKey);
191 if (FAILED(hr))
193 RegCloseKey(*phKey);
194 }
195 return SHRegDuplicateHKey(hClass, phKey);
196}
197
198static inline HRESULT GetClassKeyName(ASSOCF fA, PCWSTR pszSource, HKEY hSource, LPWSTR pszClass, UINT cchMax)
199{
200 PCWSTR pszSubKey = *pszSource == L'{' ? L"ProgID" : NULL;
201 return SHELL_RegGetString(hSource, pszSubKey, NULL, pszClass, cchMax);
202}
203
204static HRESULT OpenClassKey(ASSOCF fA, PCWSTR pszSource, HKEY hCR, HKEY hSource, HKEY *phKey)
205{
206 WCHAR szBuf[MAX_PATH];
207 HRESULT hr = E_FAIL;
208 if (*pszSource == L'.' || (*pszSource == L'{' && !(fA & ASSOCF_INIT_NOREMAPCLSID)))
209 {
210 hr = GetClassKeyName(fA, pszSource, hSource, szBuf, _countof(szBuf));
211 if (FAILED(hr) && *pszSource == L'.')
212 return hr; // .ext can only have its ProgId in another location
213 }
214
216 if (SUCCEEDED(hr))
218 else
219 hr = SHRegDuplicateHKey(hSource, &hClassKey);
220
221 if (FAILED(hr))
222 return hr;
223
224 // Check for CurVer redirection
225 if (SUCCEEDED(SHELL_RegGetString(hClassKey, L"CurVer", NULL, szBuf, _countof(szBuf))))
226 {
227 if (RegOpenKeyExW(hCR, szBuf, 0, KEY_READ, phKey) == ERROR_SUCCESS)
228 {
229 if (RegKeyExists(*phKey, L"shell")) // Does it look like a valid ProgId?
230 {
232 return S_OK;
233 }
234 RegCloseKey(*phKey);
235 }
236 }
237 *phKey = hClassKey;
238 return hr;
239}
240
241static HRESULT OpenClassKey(ASSOCF fA, const WCHAR *const pszSource, HKEY *phKey)
242{
243 // TODO: Handle the FileExts key and ASSOCF_NOUSERSETTINGS?
244 PCWSTR pszSourcePath = pszSource;
245 WCHAR buf[100];
246 if (*pszSource == L'{')
247 {
248 HRESULT hr = StringCchPrintfW(buf, _countof(buf), L"CLSID\\%s", pszSource);
249 if (FAILED(hr))
250 return hr;
251 pszSourcePath = buf;
252 }
253 ClassesRegKey cr;
254 if (HRESULT hr = cr.Initialize(fA, pszSource))
255 return hr;
256 HKEY hSourceKey;
257 LONG err = RegOpenKeyExW(cr.hKey, pszSourcePath, 0, KEY_READ, &hSourceKey);
258 if (err)
259 return HResultFromWin32(err);
260 HRESULT hr = OpenClassKey(fA, pszSource, cr.hKey, hSourceKey, phKey);
261 RegCloseKey(hSourceKey);
262 return hr;
263}
264
265/**************************************************************************
266 * IQueryAssociations
267 *
268 * DESCRIPTION
269 * This object provides a layer of abstraction over the system registry in
270 * order to simplify the process of parsing associations between files.
271 * Associations in this context means the registry entries that link (for
272 * example) the extension of a file with its description, list of
273 * applications to open the file with, and actions that can be performed on it
274 * (the shell displays such information in the context menu of explorer
275 * when you right-click on a file).
276 *
277 * HELPERS
278 * You can use this object transparently by calling the helper functions
279 * AssocQueryKeyA(), AssocQueryStringA() and AssocQueryStringByKeyA(). These
280 * create an IQueryAssociations object, perform the requested actions
281 * and then dispose of the object. Alternatively, you can create an instance
282 * of the object using AssocCreate() and call the following methods on it:
283 *
284 * METHODS
285 */
286
287CQueryAssociations::CQueryAssociations() : hkeySource(0), hkeyProgID(0), m_InitFlags(0), m_InitType(0)
288{
289}
290
292{
293 Reset();
294}
295
297{
298 if (hkeySource)
303 m_InitType = 0;
304}
305
307{
308 if (!hKey)
310 return SHRegDuplicateHKey(hKey, phKey);
311}
312
314{
316 return NULL;
317 else if (m_pBaseClass)
318 return m_pBaseClass;
319
321 if (FAILED(ShellObjectCreator(pQA)))
322 return NULL;
323
325 PWSTR classes[3] = { }; // Note: Without dynamic array support we can only emulate Windows 2000 here
326 if (EmulateWin2000()) // BaseClass is present in the registry but it does not seem to act like a base class on XP+
327 SHELL_RegGetStringAlloc(GetClassHandle(), NULL, L"BaseClass", classes[0]); // AudioCD/DVD etc.
329 classes[1] = const_cast<PWSTR>(L"Folder");
331 classes[2] = const_cast<PWSTR>(L"*");
332 for (UINT i = 0; i < _countof(classes); ++i, initflags = 0)
333 {
334 if (FAILED(pQA->Init(initflags, classes[i], 0, NULL)))
335 continue;
336 m_pBaseClass = pQA;
337 break;
338 }
339 SHFree(classes[0]);
341 return m_pBaseClass;
342}
343
345{
346 HKEY hClass = GetClassHandle();
347 if (!hClass)
349 HKEY hKey, hSubKey;
350 HRESULT hr = ::OpenShellVerbKey(hClass, pszVerb, &hKey);
351 if (FAILED(hr))
352 return hr;
353
354 if (pszSubKey)
355 {
358 if (FAILED(hr))
359 return hr;
360 hKey = hSubKey;
361 }
362 KeyRef.Attach(hKey);
363 return hr;
364}
365
366/**************************************************************************
367 * IQueryAssociations_Init
368 *
369 * Initialise an IQueryAssociations object.
370 *
371 * PARAMS
372 * cfFlags [I] ASSOCF_ flags from "shlwapi.h"
373 * pszAssoc [I] String for the root key name, or NULL if hkeyProgid is given
374 * hkeyProgid [I] Handle for the root key, or NULL if pszAssoc is given
375 * hWnd [I] Reserved, must be NULL.
376 *
377 * RETURNS
378 * Success: S_OK. iface is initialised with the parameters given.
379 * Failure: An HRESULT error code indicating the error.
380 */
382 ASSOCF cfFlags,
383 LPCWSTR pszAssoc,
384 HKEY hkeyProgid,
385 HWND hWnd)
386{
387 TRACE("(%p)->(%d,%s,%p,%p)\n", this,
388 cfFlags,
389 debugstr_w(pszAssoc),
390 hkeyProgid,
391 hWnd);
392
393 enum { HANDLEDINITFLAGS = ASSOCF_INIT_BYEXENAME | ASSOCF_INIT_NOREMAPCLSID };
394 HRESULT hr;
395 Reset();
396 m_InitFlags = cfFlags;
397
398 if (hWnd != NULL)
399 FIXME("hwnd != NULL not supported\n");
400
401 if (cfFlags & ~HANDLEDINITFLAGS)
402 FIXME("unsupported flags: %#x\n", cfFlags & ~HANDLEDINITFLAGS);
403
404 if (pszAssoc != NULL)
405 {
406 WCHAR buf[sizeof("Applications") + MAX_PATH];
407 m_InitType = *pszAssoc <= 0xff ? LOBYTE(*pszAssoc) : 'P';
408
409 if (cfFlags & ASSOCF_INIT_BYEXENAME)
410 {
411 m_InitType = 'A';
412 PCWSTR pszAppFile = PathFindFileNameW(pszAssoc);
413 PCWSTR pszDotExt = *PathFindExtensionW(pszAppFile) ? L"" : L".exe";
414 hr = StringCchPrintfW(buf, _countof(buf), L"%s\\%s%s", L"Applications", pszAppFile, pszDotExt);
415 if (FAILED(hr))
416 return hr;
417 pszAssoc = buf;
418 }
419 else if (*pszAssoc == L'{')
420 {
421 if (!EmulateWin2000())
422 cfFlags |= ASSOCF_INIT_NOREMAPCLSID;
423 }
424 else if (StrChrW(pszAssoc, L'\\'))
425 {
426 pszAssoc = PathFindExtensionW(pszAssoc);
427 m_InitType = (BYTE)*pszAssoc;
428 }
429
430 if (!*pszAssoc)
431 return E_INVALIDARG;
432
433 if (m_InitType == '.')
434 {
435 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, pszAssoc, 0, KEY_READ, &this->hkeySource))
436 goto done;
437 }
438 else if (m_InitType != '{' && m_InitType != 'A')
439 {
440 m_InitType = 'P'; // ProgId
441 }
442
443 OpenClassKey(cfFlags, pszAssoc, &this->hkeyProgID);
444 if (!this->hkeySource)
445 this->hkeySource = this->hkeyProgID;
446done:
447 return (!GetClassHandle() && IsNT5()) ? S_FALSE : S_OK;
448 }
449 else if (hkeyProgid != NULL)
450 {
451 /* reopen the key so we don't end up closing a key owned by the caller */
452 RegOpenKeyExW(hkeyProgid, NULL, 0, KEY_READ, &this->hkeyProgID);
453 this->hkeySource = this->hkeyProgID;
454 return S_OK;
455 }
456 else
457 {
458 return E_INVALIDARG;
459 }
460}
461
462/**************************************************************************
463 * IQueryAssociations_GetString
464 *
465 * Get a file association string from the registry.
466 *
467 * PARAMS
468 * cfFlags [I] ASSOCF_ flags from "shlwapi.h"
469 * str [I] Type of string to get (ASSOCSTR enum from "shlwapi.h")
470 * pszExtra [I] Extra information about the string location
471 * pszOut [O] Destination for the association string
472 * pcchOut [I/O] Length of pszOut
473 *
474 * RETURNS
475 * Success: S_OK. pszOut contains the string, pcchOut contains its length.
476 * Failure: An HRESULT error code indicating the error.
477 */
481 LPCWSTR pszExtra,
482 LPWSTR pszOut,
483 DWORD *pcchOut)
484{
485 const ASSOCF unimplemented_flags = ~(ASSOCF_NOTRUNCATE | ASSOCF_IGNOREBASECLASS);
486 DWORD len = 0;
488 WCHAR path[MAX_PATH], *pszResult;
489
490 TRACE("(%p)->(0x%08x, %u, %s, %p, %p)\n", this, flags, str, debugstr_w(pszExtra), pszOut, pcchOut);
491 if (flags & unimplemented_flags)
492 {
493 FIXME("%08x: unimplemented flags\n", flags & unimplemented_flags);
494 }
495
496 if (!pcchOut)
497 return E_UNEXPECTED;
498
499 if (!GetClassHandle())
500 goto trybase;
501
502 switch (str)
503 {
504 case ASSOCSTR_COMMAND:
505 {
506 hr = this->GetCommand(pszExtra, &pszResult);
507 if (SUCCEEDED(hr))
508 return this->ReturnAndFreeString(flags, pszOut, pcchOut, pszResult);
509 break;
510 }
512 {
513 hr = this->GetExecutable(pszExtra, path, MAX_PATH, &len);
514 if (SUCCEEDED(hr))
515 return this->ReturnString(flags, pszOut, pcchOut, path, ++len);
516 break;
517 }
519 {
520 WCHAR *pszFileType;
521 // FIXME: Needs to check "FriendlyTypeName" first
522 hr = this->GetValue(this->hkeySource, NULL, (void**)&pszFileType, NULL);
523 if (FAILED(hr))
524 goto trybase;
525 DWORD size = 0;
527 if (ret == ERROR_SUCCESS)
528 {
529 WCHAR *docName = static_cast<WCHAR *>(HeapAlloc(GetProcessHeap(), 0, size));
530 if (docName)
531 {
532 ret = RegGetValueW(HKEY_CLASSES_ROOT, pszFileType, NULL, RRF_RT_REG_SZ, NULL, docName, &size);
533 if (ret == ERROR_SUCCESS)
534 {
535 hr = this->ReturnString(flags, pszOut, pcchOut, docName, strlenW(docName) + 1);
536 }
537 else
538 {
540 }
541 HeapFree(GetProcessHeap(), 0, docName);
542 }
543 else
544 {
546 }
547 }
548 else
549 {
551 }
552 HeapFree(GetProcessHeap(), 0, pszFileType);
553 return hr;
554 }
556 {
557 PVOID verinfoW = NULL;
558 DWORD size, retval = 0;
559 UINT flen;
560 WCHAR *bufW;
561 WCHAR fileDescW[41];
562
563 hr = this->GetExecutable(pszExtra, path, MAX_PATH, &len);
564 if (FAILED(hr))
565 {
566 return hr;
567 }
569 if (!retval)
570 {
571 goto get_friendly_name_fail;
572 }
574 if (!verinfoW)
575 {
576 return E_OUTOFMEMORY;
577 }
578 if (!GetFileVersionInfoW(path, 0, retval, verinfoW))
579 {
580 goto get_friendly_name_fail;
581 }
582 if (VerQueryValueW(verinfoW, L"\\VarFileInfo\\Translation", (LPVOID *)&bufW, &flen))
583 {
584 UINT i;
585 DWORD *langCodeDesc = (DWORD *)bufW;
586 for (i = 0; i < flen / sizeof(DWORD); i++)
587 {
588 sprintfW(fileDescW, L"\\StringFileInfo\\%04x%04x\\FileDescription",
589 LOWORD(langCodeDesc[i]), HIWORD(langCodeDesc[i]));
590 if (VerQueryValueW(verinfoW, fileDescW, (LPVOID *)&bufW, &flen))
591 {
592 /* Does strlenW(bufW) == 0 mean we use the filename? */
593 len = strlenW(bufW) + 1;
594 TRACE("found FileDescription: %s\n", debugstr_w(bufW));
595 hr = this->ReturnString(flags, pszOut, pcchOut, bufW, len);
596 HeapFree(GetProcessHeap(), 0, verinfoW);
597 return hr;
598 }
599 }
600 }
601 get_friendly_name_fail:
604 TRACE("using filename: %s\n", debugstr_w(path));
605 hr = this->ReturnString(flags, pszOut, pcchOut, path, strlenW(path) + 1);
606 HeapFree(GetProcessHeap(), 0, verinfoW);
607 return hr;
608 }
610 {
611 hr = SHELL_RegGetStringAlloc(this->hkeySource, NULL, L"Content Type", pszResult);
612 if (SUCCEEDED(hr))
613 return ReturnAndFreeString(flags, pszOut, pcchOut, pszResult, hr / sizeof(WCHAR));
614 break;
615 }
617 {
618 for (HKEY hKey = GetClassHandle();; hKey = this->hkeySource) // ProgId or .ext
619 {
620 hr = SHELL_RegGetStringAlloc(hKey, L"DefaultIcon", NULL, pszResult);
621 if (SUCCEEDED(hr))
622 return ReturnAndFreeString(flags, pszOut, pcchOut, pszResult, hr / sizeof(WCHAR));
623 else if (hKey == this->hkeySource)
624 break;
625 }
626 break;
627 }
628 case ASSOCSTR_INFOTIP:
629 {
630 hr = SHELL_RegGetStringAlloc(GetClassHandle(), NULL, L"InfoTip", pszResult);
631 if (SUCCEEDED(hr))
632 return ReturnAndFreeString(flags, pszOut, pcchOut, pszResult, hr / sizeof(WCHAR));
633 // TODO: On Vista+, if not even the base class nor "*" provides a tip, it returns a default?
634 break;
635 }
637 {
638 WCHAR keypath[ARRAY_SIZE(L"ShellEx\\") + 39], guid[39];
639 CLSID clsid;
640 HKEY hkey;
641
642 hr = CLSIDFromString(pszExtra, &clsid);
643 if (FAILED(hr))
644 {
645 return hr;
646 }
647 strcpyW(keypath, L"ShellEx\\");
648 strcatW(keypath, pszExtra);
649 LONG ret = RegOpenKeyExW(this->hkeySource, keypath, 0, KEY_READ, &hkey);
650 if (ret)
651 {
652 return HRESULT_FROM_WIN32(ret);
653 }
654 DWORD size = sizeof(guid);
656 RegCloseKey(hkey);
657 if (ret)
658 {
659 return HRESULT_FROM_WIN32(ret);
660 }
661 return this->ReturnString(flags, pszOut, pcchOut, guid, size / sizeof(WCHAR));
662 }
663
664 default:
665 {
666 FIXME("assocstr %d unimplemented!\n", str);
667 return E_NOTIMPL;
668 }
669 }
670trybase:
671 if (FAILED(hr) && TryBaseClass(flags))
672 hr = m_pBaseClass->GetString(flags, str, pszExtra, pszOut, pcchOut);
673 return hr;
674}
675
676/**************************************************************************
677 * IQueryAssociations_GetKey
678 *
679 * Get a file association key from the registry.
680 *
681 * PARAMS
682 * cfFlags [I] ASSOCF_ flags from "shlwapi.h"
683 * assockey [I] Type of key to get (ASSOCKEY enum from "shlwapi.h")
684 * pszExtra [I] Extra information about the key location
685 * phkeyOut [O] Destination for the association key
686 *
687 * RETURNS
688 * Success: S_OK. phkeyOut contains a handle to the key.
689 * Failure: An HRESULT error code indicating the error.
690 */
692 ASSOCF cfFlags,
693 ASSOCKEY assockey,
694 LPCWSTR pszExtra,
695 HKEY *phkeyOut)
696{
698 HKEY hClass = GetClassHandle();
699 const CLSID *pAssocElement = NULL;
700 ASSOCSTR strInit = (ASSOCSTR)0;
702 PCWSTR pszSetString = NULL;
703 *phkeyOut = NULL; // Note: Windows does not check if the pointer is valid
704
705 switch (assockey)
706 {
708 cfFlags |= ASSOCF_VERIFY;
709 if (hClass && SUCCEEDED(hr = OpenClassWithShellExecKey(cfFlags, hClass, pszExtra, phkeyOut)))
710 return hr;
712 break;
713 case ASSOCKEY_APP:
715 {
716 pszExtra = NULL; // Always ignored
717 return DuplicateHKey(this->hkeySource, phkeyOut);
718 }
719 pAssocElement = &CLSID_AssocApplicationElement;
720 strInit = ASSOCSTR_EXECUTABLE;
722 break;
723 case ASSOCKEY_CLASS: // "A ProgID or class key"
724 if (hClass)
725 return DuplicateHKey(hClass, phkeyOut);
727 break;
729 assockey = ASSOCKEY_CLASS;
730 break;
731 case ASSOCKEY_MAX:
732 // fallthrough
733 default:
734 FIXME("(%p,0x%8x,0x%8x,%s,%p)\n", this, cfFlags, assockey, debugstr_w(pszExtra), phkeyOut);
735 }
736
737 if (strInit)
738 {
741 pszSetString = buf;
742 }
743 if (pAssocElement && pszSetString)
744 {
746 if (FAILED(SH32_AssocCreateElement(*pAssocElement, IID_PPV_ARG(IPersistString2, &pPS2))))
747 return hr;
748 if (FAILED(pPS2->SetString(pszSetString)))
749 return hr;
750 hr = GetKeyFromObjectWithQuerySource(*pPS2, phkeyOut);
751 }
752
753 if (FAILED(hr) && TryBaseClass(cfFlags))
754 hr = m_pBaseClass->GetKey(cfFlags, assockey, pszExtra, phkeyOut);
755 return hr;
756}
757
758/**************************************************************************
759 * IQueryAssociations_GetData
760 *
761 * Get the data for a file association key from the registry.
762 *
763 * PARAMS
764 * cfFlags [I] ASSOCF_ flags from "shlwapi.h"
765 * assocdata [I] Type of data to get (ASSOCDATA enum from "shlwapi.h")
766 * pszExtra [I] Extra information about the data location
767 * pvOut [O] Destination for the association key
768 * pcbOut [I/O] Size of pvOut
769 *
770 * RETURNS
771 * Success: S_OK. pszOut contains the data, pcbOut contains its length.
772 * Failure: An HRESULT error code indicating the error.
773 */
775{
776 TRACE("(%p,0x%8x,0x%8x,%s,%p,%p)\n", this, cfFlags, assocdata,
777 debugstr_w(pszExtra), pvOut, pcbOut);
778
779 enum { HANDLEDFLAGS = ASSOCF_IGNOREBASECLASS };
781 HKEY hClass = GetClassHandle();
782 RegKeyRef rkr;
783
784 if (cfFlags & ~HANDLEDFLAGS)
785 FIXME("Unsupported flags: %x\n", cfFlags & ~HANDLEDFLAGS);
786
787 switch(assocdata)
788 {
790 if (SUCCEEDED(OpenDdeKey(cfFlags, pszExtra, rkr)))
791 hr = ReturnRegData(cfFlags, rkr, L"NoActivateHandler", pvOut, pcbOut);
792 break;
794 if (hClass)
795 hr = ReturnRegData(cfFlags, hClass, L"QueryClassStore", pvOut, pcbOut);
796 break;
798 if (hClass)
799 hr = ReturnRegData(cfFlags, hClass, L"EditFlags", pvOut, pcbOut);
800 break;
801 case ASSOCDATA_VALUE:
802 if (hClass)
803 hr = ReturnRegData(cfFlags, hClass, pszExtra, pvOut, pcbOut);
804 break;
805 default:
806 {
807 FIXME("Unsupported ASSOCDATA value: %d\n", assocdata);
808 return E_NOTIMPL;
809 }
810 }
811 if (FAILED(hr) && TryBaseClass(cfFlags))
812 hr = m_pBaseClass->GetData(cfFlags, assocdata, pszExtra, pvOut, pcbOut);
813 return hr;
814}
815
817{
818 if (!pcbOut) // Asking if the data exists without returning it
819 return RegValueExists(hKey, pszName) ? S_OK : S_FALSE;
820
821 void *pData;
823 HRESULT hr = this->GetValue(hKey, pszName, &pData, &cbData);
824 if (FAILED(hr))
825 return hr;
826 hr = this->ReturnData(pvOut, pcbOut, pData, cbData);
828 return hr;
829}
830
831/**************************************************************************
832 * IQueryAssociations_GetEnum
833 *
834 * Not yet implemented in native Win32.
835 *
836 * PARAMS
837 * cfFlags [I] ASSOCF_ flags from "shlwapi.h"
838 * assocenum [I] Type of enum to get (ASSOCENUM enum from "shlwapi.h")
839 * pszExtra [I] Extra information about the enum location
840 * riid [I] REFIID to look for
841 * ppvOut [O] Destination for the interface.
842 *
843 * RETURNS
844 * Success: S_OK.
845 * Failure: An HRESULT error code indicating the error.
846 *
847 * NOTES
848 * Presumably this function returns an enumerator object.
849 */
851 ASSOCF cfFlags,
852 ASSOCENUM assocenum,
853 LPCWSTR pszExtra,
854 REFIID riid,
855 LPVOID *ppvOut)
856{
857 return E_NOTIMPL;
858}
859
861{
862 DWORD size;
863 LONG ret;
864
865 ret = SHQueryValueExW(hkey, name, 0, NULL, NULL, &size);
866 if (ret != ERROR_SUCCESS)
867 return HRESULT_FROM_WIN32(ret);
868
869 if (!size)
870 return E_FAIL;
871
873 if (!*data)
874 return E_OUTOFMEMORY;
875
876 ret = SHQueryValueExW(hkey, name, 0, NULL, (LPBYTE)*data, &size);
877 if (ret != ERROR_SUCCESS)
878 {
880 return HRESULT_FROM_WIN32(ret);
881 }
882
883 if (data_size)
884 *data_size = size;
885
886 return S_OK;
887}
888
890{
891 HKEY hClass = GetClassHandle();
892 if (!hClass)
893 return E_UNEXPECTED;
894 return SH32_QueryAssocElementString(CLSID_AssocProgidElement, ASSOCQUERY_COMMAND, hClass, NULL, extra, command);
895}
896
898{
899 PWSTR pszCommand, pszStart, pszEnd, pszBuf, pszFree;
900 HRESULT hr = this->GetCommand(pszExtra, &pszCommand);
901 if (FAILED(hr))
902 return hr;
903
904 DWORD expLen = ExpandEnvironmentStringsW(pszCommand, NULL, 0);
905 if (expLen > 0)
906 {
907 pszBuf = (PWSTR)SHAlloc(++expLen * sizeof(WCHAR));
908 if (!pszBuf)
909 {
910 SHFree(pszCommand);
911 return E_OUTOFMEMORY;
912 }
913 ExpandEnvironmentStringsW(pszCommand, pszBuf, expLen);
914 SHFree(pszCommand);
915 pszCommand = pszBuf;
916 }
917 pszFree = pszCommand;
918
919 // ASSOCF_REMAPRUNDLL implied for ASSOCSTR_EXECUTABLE
920 pszEnd = PathGetArgsW(pszCommand);
921 WCHAR save = *pszEnd;
922 *pszEnd = UNICODE_NULL;
923 pszStart = PathFindFileNameW(pszCommand + (*pszCommand == '"'));
924 *pszEnd = save;
925 if (!StrCmpNIW(pszStart, L"rundll", _countof(L"rundll") - 1))
926 {
927 pszCommand = pszEnd;
928 if ((pszEnd = StrChrW(pszCommand, ',')) != NULL)
929 *pszEnd = UNICODE_NULL; // Remove comma and function name
930 }
931
932 /* cleanup pszCommand */
933 if (pszCommand[0] == '"')
934 {
935 pszStart = pszCommand + 1;
936 pszEnd = strchrW(pszStart, '"');
937 if (pszEnd)
938 {
939 *pszEnd = 0;
940 }
941 *len = SearchPathW(NULL, pszStart, NULL, pathlen, path, NULL);
942 }
943 else
944 {
945 pszStart = pszCommand;
946 for (pszEnd = pszStart; (pszEnd = strchrW(pszEnd, ' ')); pszEnd++)
947 {
948 WCHAR c = *pszEnd;
949 *pszEnd = 0;
950 if ((*len = SearchPathW(NULL, pszStart, NULL, pathlen, path, NULL)))
951 {
952 break;
953 }
954 *pszEnd = c;
955 }
956 if (!pszEnd)
957 {
958 *len = SearchPathW(NULL, pszStart, NULL, pathlen, path, NULL);
959 }
960 }
961
962 SHFree(pszFree);
963 if (!*len)
964 {
966 }
967 return S_OK;
968}
969
971{
972 if (out)
973 {
974 DWORD lenNoReturn = PtrToUlong(outlen);
975 if (IS_INTRESOURCE(outlen) && IsNT5())
976 outlen = &lenNoReturn;
977
978 if (*outlen < datalen)
979 {
980 *outlen = datalen;
981 return E_POINTER;
982 }
983 *outlen = datalen;
985 return S_OK;
986 }
987 else
988 {
989 *outlen = datalen;
990 return S_FALSE;
991 }
992}
993
995{
996 HRESULT hr = S_OK;
997 DWORD len;
998
999 TRACE("flags=0x%08x, data=%s\n", flags, debugstr_w(data));
1000
1001 if (!out)
1002 {
1003 *outlen = datalen;
1004 return S_FALSE;
1005 }
1006
1007 DWORD lenNoReturn = PtrToUlong(outlen);
1008 if (IS_INTRESOURCE(outlen) && IsNT5())
1009 outlen = &lenNoReturn;
1010
1011 if (*outlen < datalen)
1012 {
1014 {
1015 len = 0;
1016 if (*outlen > 0) out[0] = 0;
1017 hr = E_POINTER;
1018 }
1019 else
1020 {
1021 len = min(*outlen, datalen);
1023 }
1024 *outlen = datalen;
1025 }
1026 else
1027 {
1028 *outlen = len = datalen;
1029 }
1030
1031 if (len)
1032 {
1033 memcpy(out, data, len*sizeof(WCHAR));
1034 }
1035
1036 return hr;
1037}
static HRESULT AssocCreateElementInternal(REFCLSID rclsid, IQuerySource *pQS, REFIID riid, PVOID *ppv)
static HRESULT OpenClassWithShellExecKey(ASSOCF fA, HKEY hClass, LPCWSTR pszVerb, HKEY *phKey)
static HRESULT GetKeyFromObjectWithQuerySource(T &Obj, HKEY *phKey)
static HRESULT GetClassKeyName(ASSOCF fA, PCWSTR pszSource, HKEY hSource, LPWSTR pszClass, UINT cchMax)
static HRESULT SH32_QueryAssocElementString(_In_ REFCLSID rclsid, _In_ UINT Query, _In_ HKEY hKey, _In_opt_ PCWSTR pszSubKey, _In_ PCWSTR pszExtra, _Out_ PWSTR *ppszValue)
static HRESULT OpenShellVerbKey(HKEY hClass, LPCWSTR pszVerb, HKEY *phKey)
static HRESULT SHRegDuplicateHKey(HKEY hKey, HKEY *phKey)
static HRESULT SH32_AssocCreateElementOnKey(_In_ REFCLSID rclsid, _In_ HKEY hKey, _In_opt_ PCWSTR pszSubKey, _In_ REFIID riid, _Outptr_ PVOID *ppv)
EXTERN_C HRESULT SHELL32_AssocGetFileDescription(PCWSTR Name, PWSTR Buf, UINT cchBuf)
static HRESULT GetExtensionDefaultDescription(PCWSTR DotExt, PWSTR Buf, UINT cchBuf)
EXTERN_C HRESULT SHELL32_AssocGetFSDirectoryDescription(PWSTR Buf, UINT cchBuf)
static HRESULT SHELL32_AssocGetExtensionDescription(PCWSTR DotExt, PWSTR Buf, UINT cchBuf)
static HRESULT AssocCreateElementOnKeyInternal(_In_ REFCLSID rclsid, _In_ HKEY hKey, _In_opt_ PCWSTR pszSubKey, _In_ REFIID riid, _Outptr_ PVOID *ppv, _In_ BYTE Major)
static HRESULT SH32_AssocCreateElement(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ PVOID *ppv)
static HRESULT OpenClassKey(ASSOCF fA, PCWSTR pszSource, HKEY hCR, HKEY hSource, HKEY *phKey)
#define shell32_hInstance
UINT cchMax
static adns_initflags initflags
Definition: adnsresfilter.c:62
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define ARRAY_SIZE(A)
Definition: main.h:20
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
HKEY hClassKey
Definition: umpnpmgr.c:45
#define FIXME(fmt,...)
Definition: precomp.h:53
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
#define RegCloseKey(hKey)
Definition: registry.h:49
CComPtr< CQueryAssociations > m_pBaseClass
HRESULT GetValue(HKEY hkey, const WCHAR *name, void **data, DWORD *data_size)
HRESULT OpenDdeKey(ASSOCF flags, LPCWSTR pszExtra, RegKeyRef &KeyRef)
HRESULT ReturnString(ASSOCF flags, LPWSTR out, DWORD *outlen, LPCWSTR data, DWORD datalen)
HKEY GetClassHandle() const
HRESULT ReturnRegData(ASSOCF flags, HKEY hKey, PCWSTR pszName, void *pvOut, DWORD *pcbOut)
HRESULT OpenShellVerbKey(ASSOCF flags, LPCWSTR pszVerb, LPCWSTR pszSubKey, RegKeyRef &KeyRef)
HRESULT GetCommand(const WCHAR *extra, WCHAR **command)
CQueryAssociations * TryBaseClass(ASSOCF flags)
HRESULT ReturnData(void *out, DWORD *outlen, const void *data, DWORD datalen)
HRESULT GetExecutable(LPCWSTR pszExtra, LPWSTR path, DWORD pathlen, DWORD *len)
STDMETHOD() GetEnum(ASSOCF cfFlags, ASSOCENUM assocenum, LPCWSTR pszExtra, REFIID riid, LPVOID *ppvOut) override
STDMETHOD() GetString(ASSOCF flags, ASSOCSTR str, LPCWSTR pwszExtra, LPWSTR pwszOut, DWORD *pcchOut) override
STDMETHOD() Init(ASSOCF flags, LPCWSTR pwszAssoc, HKEY hkProgid, HWND hwnd) override
bool EmulateWin2000() const
HRESULT ReturnAndFreeString(ASSOCF flags, LPWSTR out, DWORD *outlen, LPWSTR data, DWORD datalen)
STDMETHOD() GetData(ASSOCF flags, ASSOCDATA data, LPCWSTR pwszExtra, void *pvOut, DWORD *pcbOut) override
STDMETHOD() GetKey(ASSOCF flags, ASSOCKEY key, LPCWSTR pwszExtra, HKEY *phkeyOut) override
HRESULT DuplicateHKey(HKEY hKey, HKEY *phKey)
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#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
LPWSTR Name
Definition: desk.c:124
LONG RegLoadMUIStringW(IN HKEY hKey, IN LPCWSTR pszValue OPTIONAL, OUT LPWSTR pszOutBuf, IN DWORD cbOutBuf, OUT LPDWORD pcbData OPTIONAL, IN DWORD Flags, IN LPCWSTR pszDirectory OPTIONAL)
Definition: muireg.c:53
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
HRESULT WINAPI CLSIDFromString(LPCOLESTR str, LPCLSID clsid)
Definition: combase.c:1470
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:307
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR *const ext[]
Definition: module.c:53
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:492
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen)
Definition: locale.c:3808
#define IS_INTRESOURCE(x)
Definition: loader.c:613
void WINAPI PathRemoveExtensionW(WCHAR *path)
Definition: path.c:1922
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1677
void WINAPI PathStripPathW(WCHAR *path)
Definition: path.c:2304
LPWSTR WINAPI PathFindExtensionW(const WCHAR *path)
Definition: path.c:1250
WCHAR *WINAPI PathGetArgsW(const WCHAR *path)
Definition: path.c:1716
BOOL WINAPI StrTrimW(WCHAR *str, const WCHAR *trim)
Definition: string.c:804
GUID guid
Definition: version.c:147
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:967
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1171
DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR filename, LPDWORD handle)
Definition: version.c:738
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
static const struct win_class_data classes[]
Definition: client.c:872
DWORD WINAPI SHQueryValueExW(HKEY hkey, const WCHAR *name, DWORD *reserved, DWORD *type, void *buff, DWORD *buff_len)
Definition: main.c:2101
HKEY WINAPI SHRegDuplicateHKey(HKEY hKey)
Definition: main.c:1828
#define IDS_ANY_FILE
Definition: resource.h:5
BOOL RegKeyExists(HKEY hKey, LPCWSTR Path)
Definition: utils.h:49
static BOOL RegValueExists(HKEY hKey, LPCWSTR Name)
Definition: utils.h:43
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:370
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:348
HRESULT WINAPI AssocCreate(CLSID clsid, REFIID refiid, void **lpInterface)
Definition: assoc.c:213
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
#define PtrToUlong(u)
Definition: config.h:107
EXTERN_C HRESULT WINAPI AssocCreateElement(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ PVOID *ppvObj)
Definition: elements.cpp:1612
#define ASSOCQUERY_COMMAND
Definition: elements.h:25
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT
Definition: sysinfo.c:13
@ extra
Definition: id3.c:95
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define C_ASSERT(e)
Definition: intsafe.h:73
#define LOBYTE(W)
Definition: jmemdos.c:487
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1033
#define c
Definition: ke_i.h:80
#define debugstr_w
Definition: kernel32.h:32
#define HResultFromWin32
Definition: loader.cpp:14
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
LPCWSTR szPath
Definition: env.c:37
#define min(a, b)
Definition: monoChain.cc:55
const CLSID * clsid
Definition: msctf.cpp:50
#define _Outptr_
Definition: no_sal2.h:262
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define KEY_READ
Definition: nt_native.h:1026
#define DWORD
Definition: nt_native.h:44
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define LOCALE_USER_DEFAULT
#define UNICODE_NULL
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
ASSOCDATA
Definition: shlwapi.h:926
@ ASSOCDATA_EDITFLAGS
Definition: shlwapi.h:932
@ ASSOCDATA_VALUE
Definition: shlwapi.h:933
@ ASSOCDATA_NOACTIVATEHANDLER
Definition: shlwapi.h:928
@ ASSOCDATA_QUERYCLASSSTORE
Definition: shlwapi.h:929
ASSOCSTR
Definition: shlwapi.h:885
@ ASSOCSTR_CONTENTTYPE
Definition: shlwapi.h:900
@ ASSOCSTR_SHELLEXTENSION
Definition: shlwapi.h:902
@ ASSOCSTR_COMMAND
Definition: shlwapi.h:886
@ ASSOCSTR_FRIENDLYDOCNAME
Definition: shlwapi.h:888
@ ASSOCSTR_INFOTIP
Definition: shlwapi.h:896
@ ASSOCSTR_FRIENDLYAPPNAME
Definition: shlwapi.h:889
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:887
@ ASSOCSTR_DEFAULTICON
Definition: shlwapi.h:901
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
@ ASSOCF_NOFIXUPS
Definition: shlwapi.h:868
@ ASSOCF_INIT_DEFAULTTOSTAR
Definition: shlwapi.h:862
@ ASSOCF_PER_MACHINE_ONLY
Definition: shlwapi.h:878
@ ASSOCF_INIT_DEFAULTTOFOLDER
Definition: shlwapi.h:863
@ ASSOCF_IGNOREBASECLASS
Definition: shlwapi.h:869
@ ASSOCF_INIT_NOREMAPCLSID
Definition: shlwapi.h:859
@ ASSOCF_VERIFY
Definition: shlwapi.h:866
@ ASSOCF_INIT_IGNOREUNKNOWN
Definition: shlwapi.h:870
@ ASSOCF_NOTRUNCATE
Definition: shlwapi.h:865
@ ASSOCF_INIT_BYEXENAME
Definition: shlwapi.h:860
ASSOCKEY
Definition: shlwapi.h:918
@ ASSOCKEY_CLASS
Definition: shlwapi.h:921
@ ASSOCKEY_SHELLEXECCLASS
Definition: shlwapi.h:919
@ ASSOCKEY_MAX
Definition: shlwapi.h:923
@ ASSOCKEY_BASECLASS
Definition: shlwapi.h:922
@ ASSOCKEY_APP
Definition: shlwapi.h:920
_In_opt_ LPCSTR pszSubKey
Definition: shlwapi.h:783
_In_ UINT cchBuf
Definition: shlwapi.h:378
DWORD ASSOCF
Definition: shlwapi.h:967
ASSOCENUM
Definition: shlwapi.h:938
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
#define err(...)
const WCHAR * str
#define LoadStringW
Definition: utils.h:64
BOOL HCR_GetDefaultVerbW(HKEY hkeyClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len)
Definition: classes.c:152
HRESULT HCR_GetProgIdKeyOfExtension(PCWSTR szExtension, PHKEY phKey, BOOL AllowFallback)
Definition: classes.c:55
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
static HRESULT SHELL_RegGetString(HKEY hKey, PCWSTR pszPath, PCWSTR pszName, PWSTR pszOut, DWORD cchMax)
Definition: shellutils.h:141
#define IID_IObjectWithQuerySourceOld
#define IDS_DIRECTORY
Definition: shresdef.h:158
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
HRESULT Initialize(ASSOCF fA, PCWSTR pszSource)
Definition: cache.c:49
Definition: dsound.c:943
Definition: name.c:39
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define HIWORD(l)
Definition: typedefs.h:247
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
int retval
Definition: wcstombs.cpp:91
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define strchrW(s, c)
Definition: unicode.h:34
#define strlenW(s)
Definition: unicode.h:28
#define strcatW(d, s)
Definition: unicode.h:30
#define sprintfW
Definition: unicode.h:58
#define strcpyW(d, s)
Definition: unicode.h:29
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define ERROR_NO_ASSOCIATION
Definition: winerror.h:1001
#define E_UNEXPECTED
Definition: winerror.h:3528
#define E_POINTER
Definition: winerror.h:3480
#define ERROR_NOT_FOUND
Definition: winerror.h:1014
#define LCMAP_UPPERCASE
Definition: winnls.h:202
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define RRF_RT_REG_SZ
Definition: winreg.h:58
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
static void Initialize()
Definition: xlate.c:212
#define IID_PPV_ARG(Itype, ppType)
unsigned char BYTE
Definition: xxhash.c:193