ReactOS 0.4.17-dev-684-ga6524ef
CQueryAssociations Class Reference

#include <CQueryAssociations.h>

Inheritance diagram for CQueryAssociations:
Collaboration diagram for CQueryAssociations:

Classes

struct  RegKeyRef
 

Public Member Functions

 CQueryAssociations ()
 
 ~CQueryAssociations ()
 
STDMETHOD() Init (ASSOCF flags, LPCWSTR pwszAssoc, HKEY hkProgid, HWND hwnd) override
 
STDMETHOD() GetString (ASSOCF flags, ASSOCSTR str, LPCWSTR pwszExtra, LPWSTR pwszOut, DWORD *pcchOut) override
 
STDMETHOD() GetKey (ASSOCF flags, ASSOCKEY key, LPCWSTR pwszExtra, HKEY *phkeyOut) override
 
STDMETHOD() GetData (ASSOCF flags, ASSOCDATA data, LPCWSTR pwszExtra, void *pvOut, DWORD *pcbOut) override
 
STDMETHOD() GetEnum (ASSOCF cfFlags, ASSOCENUM assocenum, LPCWSTR pszExtra, REFIID riid, LPVOID *ppvOut) override
 
- Public Member Functions inherited from ATL::CComObjectRootEx< CComMultiThreadModelNoCS >
 ~CComObjectRootEx ()
 
ULONG InternalAddRef ()
 
ULONG InternalRelease ()
 
void Lock ()
 
void Unlock ()
 
HRESULT _AtlInitialConstruct ()
 
- Public Member Functions inherited from ATL::CComObjectRootBase
 CComObjectRootBase ()
 
 ~CComObjectRootBase ()
 
void SetVoid (void *)
 
HRESULT _AtlFinalConstruct ()
 
HRESULT FinalConstruct ()
 
void InternalFinalConstructAddRef ()
 
void InternalFinalConstructRelease ()
 
void FinalRelease ()
 

Private Member Functions

bool EmulateWin2000 () const
 
bool IsNT5 () const
 
void Reset ()
 
HRESULT DuplicateHKey (HKEY hKey, HKEY *phKey)
 
HKEY GetClassHandle () const
 
CQueryAssociationsTryBaseClass (ASSOCF flags)
 
HRESULT OpenShellVerbKey (ASSOCF flags, LPCWSTR pszVerb, LPCWSTR pszSubKey, RegKeyRef &KeyRef)
 
HRESULT OpenShellVerbKey (ASSOCF flags, LPCWSTR pszVerb, RegKeyRef &KeyRef)
 
HRESULT OpenDdeKey (ASSOCF flags, LPCWSTR pszExtra, RegKeyRef &KeyRef)
 
HRESULT GetValue (HKEY hkey, const WCHAR *name, void **data, DWORD *data_size)
 
HRESULT GetCommand (const WCHAR *extra, WCHAR **command)
 
HRESULT GetExecutable (LPCWSTR pszExtra, LPWSTR path, DWORD pathlen, DWORD *len)
 
HRESULT ReturnData (void *out, DWORD *outlen, const void *data, DWORD datalen)
 
HRESULT ReturnRegData (ASSOCF flags, HKEY hKey, PCWSTR pszName, void *pvOut, DWORD *pcbOut)
 
HRESULT ReturnString (ASSOCF flags, LPWSTR out, DWORD *outlen, LPCWSTR data, DWORD datalen)
 
HRESULT ReturnAndFreeString (ASSOCF flags, LPWSTR out, DWORD *outlen, LPWSTR data, DWORD datalen)
 
HRESULT ReturnAndFreeString (ASSOCF flags, LPWSTR out, DWORD *outlen, LPWSTR data)
 

Private Attributes

HKEY hkeySource
 
HKEY hkeyProgID
 
CComPtr< CQueryAssociationsm_pBaseClass
 
ASSOCF m_InitFlags
 
BYTE m_InitType
 
bool m_SkipBaseClass = false
 

Additional Inherited Members

- Static Public Member Functions inherited from ATL::CComObjectRootBase
static void WINAPI ObjectMain (bool)
 
static const struct _ATL_CATMAP_ENTRYGetCategoryMap ()
 
static HRESULT WINAPI InternalQueryInterface (void *pThis, const _ATL_INTMAP_ENTRY *pEntries, REFIID iid, void **ppvObject)
 
- Public Attributes inherited from ATL::CComObjectRootBase
LONG m_dwRef
 

Detailed Description

Definition at line 3 of file CQueryAssociations.h.

Constructor & Destructor Documentation

◆ CQueryAssociations()

CQueryAssociations::CQueryAssociations ( )

◆ ~CQueryAssociations()

CQueryAssociations::~CQueryAssociations ( )

Definition at line 291 of file CQueryAssociations.cpp.

292{
293 Reset();
294}

Member Function Documentation

◆ DuplicateHKey()

HRESULT CQueryAssociations::DuplicateHKey ( HKEY  hKey,
HKEY phKey 
)
private

Definition at line 306 of file CQueryAssociations.cpp.

307{
308 if (!hKey)
310 return SHRegDuplicateHKey(hKey, phKey);
311}
HKEY WINAPI SHRegDuplicateHKey(HKEY hKey)
Definition: main.c:1828
FxAutoRegKey hKey
#define HResultFromWin32
Definition: loader.cpp:14
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define ERROR_NO_ASSOCIATION
Definition: winerror.h:1001

Referenced by GetKey().

◆ EmulateWin2000()

bool CQueryAssociations::EmulateWin2000 ( ) const
inlineprivate

Definition at line 51 of file CQueryAssociations.h.

51{ return false; }

Referenced by Init(), and TryBaseClass().

◆ GetClassHandle()

HKEY CQueryAssociations::GetClassHandle ( ) const
inlineprivate

◆ GetCommand()

HRESULT CQueryAssociations::GetCommand ( const WCHAR extra,
WCHAR **  command 
)
private

Definition at line 889 of file CQueryAssociations.cpp.

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}
static HRESULT SH32_QueryAssocElementString(_In_ REFCLSID rclsid, _In_ UINT Query, _In_ HKEY hKey, _In_opt_ PCWSTR pszSubKey, _In_ PCWSTR pszExtra, _Out_ PWSTR *ppszValue)
HKEY GetClassHandle() const
#define NULL
Definition: types.h:112
#define ASSOCQUERY_COMMAND
Definition: elements.h:25
@ extra
Definition: id3.c:95
#define E_UNEXPECTED
Definition: winerror.h:3528

Referenced by GetExecutable(), and GetString().

◆ GetData()

HRESULT STDMETHODCALLTYPE CQueryAssociations::GetData ( ASSOCF  flags,
ASSOCDATA  data,
LPCWSTR  pwszExtra,
void pvOut,
DWORD pcbOut 
)
override

Definition at line 774 of file CQueryAssociations.cpp.

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}
#define FIXME(fmt,...)
Definition: precomp.h:53
CComPtr< CQueryAssociations > m_pBaseClass
HRESULT OpenDdeKey(ASSOCF flags, LPCWSTR pszExtra, RegKeyRef &KeyRef)
HRESULT ReturnRegData(ASSOCF flags, HKEY hKey, PCWSTR pszName, void *pvOut, DWORD *pcbOut)
CQueryAssociations * TryBaseClass(ASSOCF flags)
#define E_NOTIMPL
Definition: ddrawi.h:99
HRESULT hr
Definition: delayimp.cpp:582
#define L(x)
Definition: resources.c:13
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_w
Definition: kernel32.h:32
@ ASSOCDATA_EDITFLAGS
Definition: shlwapi.h:932
@ ASSOCDATA_VALUE
Definition: shlwapi.h:933
@ ASSOCDATA_NOACTIVATEHANDLER
Definition: shlwapi.h:928
@ ASSOCDATA_QUERYCLASSSTORE
Definition: shlwapi.h:929
@ ASSOCF_IGNOREBASECLASS
Definition: shlwapi.h:869
#define TRACE(s)
Definition: solgame.cpp:4
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210

◆ GetEnum()

HRESULT STDMETHODCALLTYPE CQueryAssociations::GetEnum ( ASSOCF  cfFlags,
ASSOCENUM  assocenum,
LPCWSTR  pszExtra,
REFIID  riid,
LPVOID ppvOut 
)
override

Definition at line 850 of file CQueryAssociations.cpp.

856{
857 return E_NOTIMPL;
858}

◆ GetExecutable()

HRESULT CQueryAssociations::GetExecutable ( LPCWSTR  pszExtra,
LPWSTR  path,
DWORD  pathlen,
DWORD len 
)
private

Definition at line 897 of file CQueryAssociations.cpp.

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}
HRESULT GetCommand(const WCHAR *extra, WCHAR **command)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:307
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
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1677
WCHAR *WINAPI PathGetArgsW(const WCHAR *path)
Definition: path.c:1716
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:370
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:348
unsigned long DWORD
Definition: ntddk_ex.h:95
const GLubyte * c
Definition: glext.h:8905
GLenum GLsizei len
Definition: glext.h:6722
#define S_OK
Definition: intsafe.h:52
#define c
Definition: ke_i.h:80
#define UNICODE_NULL
short WCHAR
Definition: pedump.c:58
#define _countof(array)
Definition: sndvol32.h:70
uint16_t * PWSTR
Definition: typedefs.h:56
#define strchrW(s, c)
Definition: unicode.h:34

Referenced by GetString().

◆ GetKey()

HRESULT STDMETHODCALLTYPE CQueryAssociations::GetKey ( ASSOCF  flags,
ASSOCKEY  key,
LPCWSTR  pwszExtra,
HKEY phkeyOut 
)
override

Definition at line 691 of file CQueryAssociations.cpp.

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}
static HRESULT OpenClassWithShellExecKey(ASSOCF fA, HKEY hClass, LPCWSTR pszVerb, HKEY *phKey)
static HRESULT GetKeyFromObjectWithQuerySource(T &Obj, HKEY *phKey)
static HRESULT SH32_AssocCreateElement(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ PVOID *ppv)
STDMETHOD() GetString(ASSOCF flags, ASSOCSTR str, LPCWSTR pwszExtra, LPWSTR pwszOut, DWORD *pcchOut) override
HRESULT DuplicateHKey(HKEY hKey, HKEY *phKey)
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define MAX_PATH
Definition: compat.h:34
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
ASSOCSTR
Definition: shlwapi.h:885
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:887
@ ASSOCF_NOFIXUPS
Definition: shlwapi.h:868
@ 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_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_ UINT _In_ UINT cch
Definition: shellapi.h:432
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define ERROR_NOT_FOUND
Definition: winerror.h:1014
#define IID_PPV_ARG(Itype, ppType)

◆ GetString()

HRESULT STDMETHODCALLTYPE CQueryAssociations::GetString ( ASSOCF  flags,
ASSOCSTR  str,
LPCWSTR  pwszExtra,
LPWSTR  pwszOut,
DWORD pcchOut 
)
override

Definition at line 478 of file CQueryAssociations.cpp.

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}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define RegCloseKey(hKey)
Definition: registry.h:49
HRESULT GetValue(HKEY hkey, const WCHAR *name, void **data, DWORD *data_size)
HRESULT ReturnString(ASSOCF flags, LPWSTR out, DWORD *outlen, LPCWSTR data, DWORD datalen)
HRESULT GetExecutable(LPCWSTR pszExtra, LPWSTR path, DWORD pathlen, DWORD *len)
HRESULT ReturnAndFreeString(ASSOCF flags, LPWSTR out, DWORD *outlen, LPWSTR data, DWORD datalen)
#define ERROR_SUCCESS
Definition: deptool.c:10
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
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
void WINAPI PathRemoveExtensionW(WCHAR *path)
Definition: path.c:1922
void WINAPI PathStripPathW(WCHAR *path)
Definition: path.c:2304
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
return ret
Definition: mutex.c:147
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
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
const CLSID * clsid
Definition: msctf.cpp:50
#define KEY_READ
Definition: nt_native.h:1026
#define DWORD
Definition: nt_native.h:44
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
@ 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_DEFAULTICON
Definition: shlwapi.h:901
DWORD ASSOCF
Definition: shlwapi.h:967
const WCHAR * str
#define HIWORD(l)
Definition: typedefs.h:247
int retval
Definition: wcstombs.cpp:91
#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 RRF_RT_REG_SZ
Definition: winreg.h:58
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10

Referenced by GetKey().

◆ GetValue()

HRESULT CQueryAssociations::GetValue ( HKEY  hkey,
const WCHAR name,
void **  data,
DWORD data_size 
)
private

Definition at line 860 of file CQueryAssociations.cpp.

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}
DWORD WINAPI SHQueryValueExW(HKEY hkey, const WCHAR *name, DWORD *reserved, DWORD *type, void *buff, DWORD *buff_len)
Definition: main.c:2101
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
Definition: name.c:39
unsigned char * LPBYTE
Definition: typedefs.h:53

Referenced by GetString(), and ReturnRegData().

◆ Init()

HRESULT STDMETHODCALLTYPE CQueryAssociations::Init ( ASSOCF  flags,
LPCWSTR  pwszAssoc,
HKEY  hkProgid,
HWND  hwnd 
)
override

Definition at line 381 of file CQueryAssociations.cpp.

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}
static HRESULT OpenClassKey(ASSOCF fA, PCWSTR pszSource, HKEY hCR, HKEY hSource, HKEY *phKey)
HWND hWnd
Definition: settings.c:17
bool EmulateWin2000() const
LPWSTR WINAPI PathFindExtensionW(const WCHAR *path)
Definition: path.c:1250
#define LOBYTE(W)
Definition: jmemdos.c:487
@ ASSOCF_INIT_NOREMAPCLSID
Definition: shlwapi.h:859
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define S_FALSE
Definition: winerror.h:3451
unsigned char BYTE
Definition: xxhash.c:193

◆ IsNT5()

bool CQueryAssociations::IsNT5 ( ) const
inlineprivate

Definition at line 52 of file CQueryAssociations.h.

52{ return LOBYTE(GetVersion()) < 6; }
DWORD WINAPI GetVersion(void)
Definition: version.c:1458

Referenced by DuplicateHKey(), GetKey(), Init(), ReturnData(), and ReturnString().

◆ OpenDdeKey()

HRESULT CQueryAssociations::OpenDdeKey ( ASSOCF  flags,
LPCWSTR  pszExtra,
RegKeyRef KeyRef 
)
inlineprivate

Definition at line 63 of file CQueryAssociations.h.

64 {
65 return OpenShellVerbKey(flags, pszExtra, L"ddeexec", KeyRef);
66 }
HRESULT OpenShellVerbKey(ASSOCF flags, LPCWSTR pszVerb, LPCWSTR pszSubKey, RegKeyRef &KeyRef)

Referenced by GetData().

◆ OpenShellVerbKey() [1/2]

HRESULT CQueryAssociations::OpenShellVerbKey ( ASSOCF  flags,
LPCWSTR  pszVerb,
LPCWSTR  pszSubKey,
RegKeyRef KeyRef 
)
private

Definition at line 344 of file CQueryAssociations.cpp.

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}
_In_opt_ LPCSTR pszSubKey
Definition: shlwapi.h:783

Referenced by OpenDdeKey(), and OpenShellVerbKey().

◆ OpenShellVerbKey() [2/2]

HRESULT CQueryAssociations::OpenShellVerbKey ( ASSOCF  flags,
LPCWSTR  pszVerb,
RegKeyRef KeyRef 
)
inlineprivate

Definition at line 59 of file CQueryAssociations.h.

60 {
61 return OpenShellVerbKey(flags, pszVerb, NULL, KeyRef);
62 }

◆ Reset()

void CQueryAssociations::Reset ( )
private

Definition at line 296 of file CQueryAssociations.cpp.

Referenced by Init(), and ~CQueryAssociations().

◆ ReturnAndFreeString() [1/2]

HRESULT CQueryAssociations::ReturnAndFreeString ( ASSOCF  flags,
LPWSTR  out,
DWORD outlen,
LPWSTR  data 
)
inlineprivate

Definition at line 80 of file CQueryAssociations.h.

81 {
82 return ReturnAndFreeString(flags, out, outlen, data, lstrlenW(data) + 1);
83 }
#define lstrlenW
Definition: compat.h:750
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

◆ ReturnAndFreeString() [2/2]

HRESULT CQueryAssociations::ReturnAndFreeString ( ASSOCF  flags,
LPWSTR  out,
DWORD outlen,
LPWSTR  data,
DWORD  datalen 
)
inlineprivate

Definition at line 74 of file CQueryAssociations.h.

75 {
77 SHFree(data);
78 return hr;
79 }
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1033

Referenced by GetString(), and ReturnAndFreeString().

◆ ReturnData()

HRESULT CQueryAssociations::ReturnData ( void out,
DWORD outlen,
const void data,
DWORD  datalen 
)
private

Definition at line 970 of file CQueryAssociations.cpp.

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}
#define IS_INTRESOURCE(x)
Definition: loader.c:613
#define PtrToUlong(u)
Definition: config.h:107
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define E_POINTER
Definition: winerror.h:3480

Referenced by ReturnRegData().

◆ ReturnRegData()

HRESULT CQueryAssociations::ReturnRegData ( ASSOCF  flags,
HKEY  hKey,
PCWSTR  pszName,
void pvOut,
DWORD pcbOut 
)
private

Definition at line 816 of file CQueryAssociations.cpp.

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}
HRESULT ReturnData(void *out, DWORD *outlen, const void *data, DWORD datalen)
static BOOL RegValueExists(HKEY hKey, LPCWSTR Name)
Definition: utils.h:43
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830

Referenced by GetData().

◆ ReturnString()

HRESULT CQueryAssociations::ReturnString ( ASSOCF  flags,
LPWSTR  out,
DWORD outlen,
LPCWSTR  data,
DWORD  datalen 
)
private

Definition at line 994 of file CQueryAssociations.cpp.

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}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define min(a, b)
Definition: monoChain.cc:55

Referenced by GetString(), and ReturnAndFreeString().

◆ TryBaseClass()

CQueryAssociations * CQueryAssociations::TryBaseClass ( ASSOCF  flags)
private

Definition at line 313 of file CQueryAssociations.cpp.

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}
static adns_initflags initflags
Definition: adnsresfilter.c:62
static const struct win_class_data classes[]
Definition: client.c:872
@ ASSOCF_INIT_DEFAULTTOSTAR
Definition: shlwapi.h:862
@ ASSOCF_INIT_DEFAULTTOFOLDER
Definition: shlwapi.h:863

Referenced by GetData(), GetKey(), and GetString().

Member Data Documentation

◆ hkeyProgID

HKEY CQueryAssociations::hkeyProgID
private

Definition at line 45 of file CQueryAssociations.h.

Referenced by GetClassHandle(), Init(), and Reset().

◆ hkeySource

HKEY CQueryAssociations::hkeySource
private

Definition at line 44 of file CQueryAssociations.h.

Referenced by GetClassHandle(), GetKey(), GetString(), Init(), and Reset().

◆ m_InitFlags

ASSOCF CQueryAssociations::m_InitFlags
private

Definition at line 47 of file CQueryAssociations.h.

Referenced by GetKey(), Init(), and TryBaseClass().

◆ m_InitType

BYTE CQueryAssociations::m_InitType
private

Definition at line 48 of file CQueryAssociations.h.

Referenced by Init(), and Reset().

◆ m_pBaseClass

CComPtr<CQueryAssociations> CQueryAssociations::m_pBaseClass
private

Definition at line 46 of file CQueryAssociations.h.

Referenced by GetData(), GetKey(), GetString(), and TryBaseClass().

◆ m_SkipBaseClass

bool CQueryAssociations::m_SkipBaseClass = false
private

Definition at line 49 of file CQueryAssociations.h.

Referenced by TryBaseClass().


The documentation for this class was generated from the following files: