mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[SHELL32][SHLWAPI][SHELL32_APITEST][SDK] Support AssocCreateElement (#9215)
Prepare for CLSID_QueryAssociations. JIRA issue: CORE-20467 - Add dll/win32/shell32/evalcmd/ elements.cpp. - Implement AssocCreateElement function in elements.cpp. - Modify shell32.spec. - Fix shlwapi!AssocCreate by using AssocCreateElement. - Add SKGetValueW and SKSetValueW prototypes into <shlwapi_undoc.h>. - Add AssocCreateElement prototype into <shlwapi_undoc.h>. - Add some CLSIDs into <shlguid_undoc.h>. - Add some resource strings into shlwapi. - Add AssocGetPerceivedType prototype into <shlwapi.h>. - Add AssocCreateElement testcase into shell32_apitest.
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
|
||||
add_library(evalcmd STATIC evalcmd.cpp)
|
||||
list(APPEND SOURCE
|
||||
evalcmd.cpp
|
||||
elements.cpp)
|
||||
|
||||
add_library(evalcmd STATIC ${SOURCE})
|
||||
add_dependencies(evalcmd psdk)
|
||||
target_link_libraries(evalcmd PRIVATE pathcch_static)
|
||||
target_link_libraries(evalcmd PRIVATE wine uuid pathcch_static cppstl)
|
||||
target_compile_definitions(evalcmd PRIVATE STATIC_PATHCCH)
|
||||
|
||||
if(DLL_EXPORT_VERSION GREATER_EQUAL 0x600)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,10 @@
|
||||
#include <strsafe.h>
|
||||
#include <pathcch.h>
|
||||
#include <assert.h>
|
||||
#include "evalcmd.h"
|
||||
|
||||
#include <wine/debug.h>
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(evalcmd);
|
||||
|
||||
#define PATH_VALID_CHARS \
|
||||
(PATH_CHAR_CLASS_DOT | PATH_CHAR_CLASS_SEMICOLON | PATH_CHAR_CLASS_COMMA | \
|
||||
@@ -45,7 +49,7 @@ static PCWSTR _PathGetArgsLikeCreateProcess(PCWSTR lpString)
|
||||
return &lpString[lstrlenW(lpString)];
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
EXTERN_C HRESULT
|
||||
_PathCopyExeAndTrimWhiteSpaces(PWSTR pszBuff, size_t cchBuff, PCWSTR pszSrc, size_t cchSrc)
|
||||
{
|
||||
HRESULT hr = StringCchCopyNW(pszBuff, cchBuff, pszSrc, cchSrc);
|
||||
@@ -140,7 +144,7 @@ static HRESULT _PathExeExists(_In_ PCWSTR pszPath)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
EXTERN_C HRESULT
|
||||
_PathFindInFolder(_In_ INT csidl, _In_ PCWSTR pszSrc, _Out_ PWSTR pszPath, _In_ UINT cchPath)
|
||||
{
|
||||
WCHAR szDir[MAX_PATH];
|
||||
@@ -155,7 +159,7 @@ _PathFindInFolder(_In_ INT csidl, _In_ PCWSTR pszSrc, _Out_ PWSTR pszPath, _In_
|
||||
return _PathExeExists(pszPath);
|
||||
}
|
||||
|
||||
static HRESULT _PathFindInSystem(_Inout_ PWSTR pszPath, _In_ UINT cchPath)
|
||||
EXTERN_C HRESULT _PathFindInSystem(_Inout_ PWSTR pszPath, _In_ UINT cchPath)
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
HRESULT hr = _PathFindInFolder(CSIDL_SYSTEM, pszPath, szPath, _countof(szPath));
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// These values must match shlwapi's ones
|
||||
#define IDS_ANY_FILE 4864
|
||||
#define IDS_FILE 4865
|
||||
#define IDS_FOLDER 4866
|
||||
@@ -326,7 +326,7 @@
|
||||
761 stub -version=0x600+ -noname SHChangeNotifyDeregisterWindow
|
||||
762 stub -version=0x600+ -noname Create_IUICommandFromDef
|
||||
763 stub -version=0x600+ -noname Create_IEnumUICommandFromDefArray
|
||||
764 stub -version=0x600+ -noname AssocCreateElement
|
||||
764 stdcall -version=0x600+ -noname AssocCreateElement(ptr ptr ptr)
|
||||
766 stub -version=0x600+ -noname SHCopyStreamWithProgress
|
||||
777 stub -version=0x600+ -noname SHGetAssocKeys
|
||||
778 stub -version=0x600+ -noname AssocGetPropListForExt
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
#include "shlguid.h"
|
||||
#include "shlobj.h"
|
||||
#include "shlwapi.h"
|
||||
#ifdef __REACTOS__
|
||||
#include "shlwapi_undoc.h"
|
||||
#include "evalcmd.h"
|
||||
#endif
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
@@ -43,6 +47,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
ASSOCF_INIT_DEFAULTTOFOLDER)
|
||||
#endif
|
||||
|
||||
#ifdef __REACTOS__
|
||||
EXTERN_C ULONG WINAPI GetProcessOsVersion(void); // FIXME: Move or delete
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
* SHLWAPI_ParamAToW
|
||||
*
|
||||
@@ -87,9 +95,11 @@ static BOOL SHLWAPI_ParamAToW(LPCSTR lpszParam, LPWSTR lpszBuff, DWORD dwLen,
|
||||
* Success: S_OK. lpInterface contains the new object.
|
||||
* Failure: An HRESULT error code indicating the error.
|
||||
*
|
||||
#ifndef __REACTOS__ // WRONG NOTES!
|
||||
* NOTES
|
||||
* clsid must be equal to CLSID_QueryAssociations and
|
||||
* refiid must be equal to IID_IQueryAssociations, IID_IUnknown or this function will fail
|
||||
#endif
|
||||
*/
|
||||
HRESULT WINAPI AssocCreate(CLSID clsid, REFIID refiid, void **lpInterface)
|
||||
{
|
||||
@@ -99,10 +109,24 @@ HRESULT WINAPI AssocCreate(CLSID clsid, REFIID refiid, void **lpInterface)
|
||||
if (!lpInterface)
|
||||
return E_INVALIDARG;
|
||||
|
||||
#ifdef __REACTOS__
|
||||
*(PVOID*)lpInterface = NULL;
|
||||
#else
|
||||
*(DWORD*)lpInterface = 0;
|
||||
#endif
|
||||
|
||||
#ifdef __REACTOS__
|
||||
if (!IsEqualGUID(&clsid, &CLSID_QueryAssociations) &&
|
||||
!IsEqualGUID(&clsid, &IID_IQueryAssociations))
|
||||
{
|
||||
if (GetProcessOsVersion() < _WIN32_WINNT_VISTA)
|
||||
return AssocCreateElement(&clsid, refiid, lpInterface);
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
#else
|
||||
if (!IsEqualGUID(&clsid, &CLSID_QueryAssociations))
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
#endif
|
||||
|
||||
return SHCoCreateInstance( NULL, &clsid, NULL, refiid, lpInterface );
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s Eo"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "このコンピューターの制限により、この操作は取り消されました。システム管理者にお問い合わせください。"
|
||||
IDS_RESTRICTIONS "システムの制限"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "Operacja została anulowana ze względu na ograniczenia nałożone na ten komputer. Skontaktuj się z administratorem systemu."
|
||||
IDS_RESTRICTIONS "Ograniczenia"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EO"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s ЭБ"
|
||||
IDS_RESTRICTED "Операция отменена из-за ограничений, действующих на этом компьютере. Обратитесь к системному администратору."
|
||||
IDS_RESTRICTIONS "Ограничения"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@ STRINGTABLE
|
||||
IDS_EB_FORMAT "%s EB"
|
||||
IDS_RESTRICTED "This operation has been cancelled due to restrictions on this computer. Please contact your system administrator."
|
||||
IDS_RESTRICTIONS "Restrictions"
|
||||
IDS_ANY_FILE "%s File"
|
||||
IDS_FILE "File"
|
||||
IDS_FOLDER "Folder"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,10 @@
|
||||
#define IDS_EB_FORMAT 73
|
||||
#define IDS_RESTRICTED 283
|
||||
#define IDS_RESTRICTIONS 284
|
||||
/* The following three values must match dll/win32/shell32/evalcmd/resource.h's ones */
|
||||
#define IDS_ANY_FILE 4864
|
||||
#define IDS_FILE 4865
|
||||
#define IDS_FOLDER 4866
|
||||
#endif
|
||||
|
||||
/* These numbers match native IDs and shouldn't be arbitrarily changed */
|
||||
|
||||
@@ -0,0 +1,582 @@
|
||||
/*
|
||||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Tests for AssocCreateElement
|
||||
* COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ <[email protected]>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <objbase.h>
|
||||
#include <shlwapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <undocshell.h>
|
||||
#include <shlobj_undoc.h>
|
||||
#include <shlguid_undoc.h>
|
||||
#include <shlwapi_undoc.h>
|
||||
#include <shellutils.h>
|
||||
#include <versionhelpers.h>
|
||||
|
||||
#define ASSOCQUERY_DE (ASSOCQUERY_DIRECT | ASSOCQUERY_EXISTS)
|
||||
#define ASSOCQUERY_SDE (ASSOCQUERY_STRING | ASSOCQUERY_DE)
|
||||
#define ASSOCQUERY_SDED (ASSOCQUERY_SDE | ASSOCQUERY_DWORD)
|
||||
#define ASSOCQUERY_SDEI (ASSOCQUERY_SDE | ASSOCQUERY_INDIRECT)
|
||||
#define ASSOCQUERY_SDEEV (ASSOCQUERY_SDE | ASSOCQUERY_EXTRA_VERB)
|
||||
|
||||
typedef HRESULT (WINAPI *FN_AssocCreateElement)(REFCLSID, REFIID, PVOID*);
|
||||
|
||||
static FN_AssocCreateElement g_fnAssocCreateElement = NULL;
|
||||
static BOOL g_bVistaPlus = FALSE;
|
||||
|
||||
static HRESULT MyAssocCreateElement(REFCLSID rclsid, REFIID riid, PVOID* ppvObj)
|
||||
{
|
||||
if (g_fnAssocCreateElement)
|
||||
return g_fnAssocCreateElement(rclsid, riid, ppvObj);
|
||||
return AssocCreate(rclsid, riid, ppvObj);
|
||||
}
|
||||
|
||||
struct CLASS_ENTRY
|
||||
{
|
||||
const CLSID *pclsid;
|
||||
PCWSTR pszName;
|
||||
};
|
||||
|
||||
static const CLASS_ENTRY g_Classes[] =
|
||||
{
|
||||
{ &CLSID_AssocShellElement, L"AssocShellElement" },
|
||||
{ &CLSID_AssocApplicationElement, L"AssocApplicationElement" },
|
||||
{ &CLSID_AssocProgidElement, L"AssocProgidElement" },
|
||||
{ &CLSID_AssocClsidElement, L"AssocClsidElement" },
|
||||
{ &CLSID_AssocSystemElement, L"AssocSystemElement" },
|
||||
{ &CLSID_AssocFolderElement, L"AssocFolderElement" },
|
||||
{ &CLSID_AssocStarElement, L"AssocStarElement" },
|
||||
{ &CLSID_AssocPerceivedElement, L"AssocPerceivedElement" },
|
||||
{ &CLSID_AssocClientElement, L"AssocClientElement" },
|
||||
};
|
||||
|
||||
// Verify that CLASS_E_CLASSNOTAVAILABLE is returned when an unknown CLSID is passed
|
||||
static void Test_InvalidClsid(void)
|
||||
{
|
||||
IUnknown *pUnk = (IUnknown *)(LONG_PTR)0xdeadbeef;
|
||||
HRESULT hr = MyAssocCreateElement(CLSID_NULL, IID_PPV_ARG(IUnknown, &pUnk));
|
||||
ok_hex(hr, CLASS_E_CLASSNOTAVAILABLE);
|
||||
ok(pUnk == NULL, "pUnk should be NULL, got %p\n", pUnk);
|
||||
}
|
||||
|
||||
// For all public CLSIDs, verify that:
|
||||
// - instantiation succeeds;
|
||||
// - IPersist / IPersistString2 / IObjectWithQuerySourceOld can be obtained; and
|
||||
// - GetClassID returns the CLSID passed during instantiation.
|
||||
static void Test_QueryInterfaceAndClassID(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
for (size_t i = 0; i < _countof(g_Classes); ++i)
|
||||
{
|
||||
const CLASS_ENTRY& entry = g_Classes[i];
|
||||
|
||||
if (g_bVistaPlus)
|
||||
{
|
||||
IAssociationElement *pElement = NULL;
|
||||
hr = MyAssocCreateElement(*entry.pclsid,
|
||||
IID_PPV_ARG(IAssociationElement, &pElement));
|
||||
ok(hr == S_OK, "[%s] AssocCreateElement failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
if (!pElement)
|
||||
continue;
|
||||
|
||||
IPersist *pPersist = NULL;
|
||||
hr = pElement->QueryInterface(IID_PPV_ARG(IPersist, &pPersist));
|
||||
ok(hr == S_OK, "[%s] QI(IPersist) failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
if (pPersist)
|
||||
{
|
||||
CLSID clsid;
|
||||
hr = pPersist->GetClassID(&clsid);
|
||||
ok(hr == S_OK, "[%s] GetClassID failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
ok(IsEqualCLSID(clsid, *entry.pclsid),
|
||||
"[%s] GetClassID returned an unexpected CLSID\n", wine_dbgstr_w(entry.pszName));
|
||||
pPersist->Release();
|
||||
}
|
||||
|
||||
IPersistString2 *pPS2 = NULL;
|
||||
hr = pElement->QueryInterface(IID_PPV_ARG(IPersistString2, &pPS2));
|
||||
ok(hr == S_OK, "[%s] QI(IPersistString2) failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
if (pPS2)
|
||||
pPS2->Release();
|
||||
|
||||
IObjectWithQuerySourceOld *pOWQS = NULL;
|
||||
hr = pElement->QueryInterface(IID_PPV_ARG(IObjectWithQuerySourceOld, &pOWQS));
|
||||
ok(hr == S_OK, "[%s] QI(IObjectWithQuerySourceOld) failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
if (pOWQS)
|
||||
pOWQS->Release();
|
||||
|
||||
pElement->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
IAssociationElementOld *pElement = NULL;
|
||||
hr = MyAssocCreateElement(*entry.pclsid,
|
||||
IID_PPV_ARG(IAssociationElementOld, &pElement));
|
||||
ok(hr == S_OK, "[%s] AssocCreateElement failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
if (!pElement)
|
||||
continue;
|
||||
|
||||
IPersist *pPersist = NULL;
|
||||
hr = pElement->QueryInterface(IID_PPV_ARG(IPersist, &pPersist));
|
||||
ok(hr == S_OK, "[%s] QI(IPersist) failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
if (pPersist)
|
||||
{
|
||||
CLSID clsid;
|
||||
hr = pPersist->GetClassID(&clsid);
|
||||
ok(hr == S_OK, "[%s] GetClassID failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
ok(IsEqualCLSID(clsid, *entry.pclsid),
|
||||
"[%s] GetClassID returned an unexpected CLSID\n", wine_dbgstr_w(entry.pszName));
|
||||
pPersist->Release();
|
||||
}
|
||||
|
||||
IPersistString2 *pPS2 = NULL;
|
||||
hr = pElement->QueryInterface(IID_PPV_ARG(IPersistString2, &pPS2));
|
||||
ok(hr == S_OK, "[%s] QI(IPersistString2) failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
if (pPS2)
|
||||
pPS2->Release();
|
||||
|
||||
IObjectWithQuerySourceOld *pOWQS = NULL;
|
||||
hr = pElement->QueryInterface(IID_PPV_ARG(IObjectWithQuerySourceOld, &pOWQS));
|
||||
ok(hr == S_OK, "[%s] QI(IObjectWithQuerySourceOld) failed: 0x%08lX\n",
|
||||
wine_dbgstr_w(entry.pszName), hr);
|
||||
if (pOWQS)
|
||||
pOWQS->Release();
|
||||
|
||||
pElement->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that calling QueryString before SetString results in E_INVALIDARG
|
||||
static void Test_QueryBeforeInit(void)
|
||||
{
|
||||
if (g_bVistaPlus)
|
||||
{
|
||||
IAssociationElement *pElement = NULL;
|
||||
HRESULT hr = MyAssocCreateElement(CLSID_AssocShellElement,
|
||||
IID_PPV_ARG(IAssociationElement, &pElement));
|
||||
ok(hr == S_OK, "AssocCreateElement failed: 0x%08lX\n", hr);
|
||||
if (!pElement)
|
||||
return;
|
||||
|
||||
PWSTR psz = NULL;
|
||||
_SEH2_TRY
|
||||
{
|
||||
hr = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
hr = 0xDEAD;
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
ok(hr == 0xDEAD, "hr was 0x%08lX\n", hr);
|
||||
|
||||
pElement->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
IAssociationElementOld *pElement = NULL;
|
||||
HRESULT hr = MyAssocCreateElement(CLSID_AssocShellElement,
|
||||
IID_PPV_ARG(IAssociationElementOld, &pElement));
|
||||
ok(hr == S_OK, "AssocCreateElement failed: 0x%08lX\n", hr);
|
||||
if (!pElement)
|
||||
return;
|
||||
|
||||
PWSTR psz = NULL;
|
||||
hr = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok_hex(hr, E_INVALIDARG);
|
||||
ok(psz == NULL, "psz should be NULL\n");
|
||||
|
||||
pElement->Release();
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that calling SetString twice results in E_UNEXPECTED
|
||||
static void Test_DoubleSetString(void)
|
||||
{
|
||||
IPersistString2 *pPS2 = NULL;
|
||||
HRESULT hr = MyAssocCreateElement(CLSID_AssocShellElement,
|
||||
IID_PPV_ARG(IPersistString2, &pPS2));
|
||||
ok(hr == S_OK, "AssocCreateElement failed: 0x%08lX\n", hr);
|
||||
if (!pPS2)
|
||||
return;
|
||||
|
||||
hr = pPS2->SetString(L"txtfile");
|
||||
ok(hr == S_OK, "First SetString failed: 0x%08lX\n", hr);
|
||||
|
||||
hr = pPS2->SetString(L"txtfile");
|
||||
if (g_bVistaPlus)
|
||||
ok_hex(hr, S_OK);
|
||||
else
|
||||
ok_hex(hr, E_UNEXPECTED);
|
||||
|
||||
pPS2->Release();
|
||||
}
|
||||
|
||||
// Retrieve FriendlyTypeName / DefaultIcon using CLSID_AssocShellElement + SetString(L"txtfile")
|
||||
static void Test_ShellElement_txtfile(void)
|
||||
{
|
||||
IPersistString2 *pPS2 = NULL;
|
||||
HRESULT hr = MyAssocCreateElement(CLSID_AssocShellElement,
|
||||
IID_PPV_ARG(IPersistString2, &pPS2));
|
||||
ok(hr == S_OK, "AssocCreateElement(AssocShellElement) failed: 0x%08lX\n", hr);
|
||||
if (!pPS2)
|
||||
return;
|
||||
|
||||
hr = pPS2->SetString(L"txtfile");
|
||||
if (hr != S_OK)
|
||||
{
|
||||
skip("\"txtfile\" ProgID was not found in HKCR, skipping\n");
|
||||
pPS2->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_bVistaPlus)
|
||||
{
|
||||
IAssociationElement *pElement = NULL;
|
||||
hr = pPS2->QueryInterface(IID_PPV_ARG(IAssociationElement, &pElement));
|
||||
ok(hr == S_OK, "QI(IAssociationElement) failed: 0x%08lX\n", hr);
|
||||
if (pElement)
|
||||
{
|
||||
PWSTR psz = NULL;
|
||||
hr = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok(hr == S_OK, "QueryString(FriendlyTypeName) failed: 0x%08lX\n", hr);
|
||||
ok(psz != NULL && psz[0] != UNICODE_NULL, "Friendly type name is empty\n");
|
||||
if (psz)
|
||||
{
|
||||
trace("txtfile FriendlyTypeName: %s\n", wine_dbgstr_w(psz));
|
||||
CoTaskMemFree(psz);
|
||||
}
|
||||
|
||||
hr = pElement->QueryExists((ASSOCQUERY_SDE | 0x1), NULL);
|
||||
ok(hr == S_OK, "QueryExists(DefaultIcon) failed: 0x%08lX\n", hr);
|
||||
|
||||
pElement->Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IAssociationElementOld *pElement = NULL;
|
||||
hr = pPS2->QueryInterface(IID_PPV_ARG(IAssociationElementOld, &pElement));
|
||||
ok(hr == S_OK, "QI(IAssociationElementOld) failed: 0x%08lX\n", hr);
|
||||
if (pElement)
|
||||
{
|
||||
PWSTR psz = NULL;
|
||||
hr = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok(hr == S_OK, "QueryString(FriendlyTypeName) failed: 0x%08lX\n", hr);
|
||||
ok(psz != NULL && psz[0] != UNICODE_NULL, "Friendly type name is empty\n");
|
||||
if (psz)
|
||||
{
|
||||
trace("txtfile FriendlyTypeName: %s\n", wine_dbgstr_w(psz));
|
||||
CoTaskMemFree(psz);
|
||||
}
|
||||
|
||||
hr = pElement->QueryExists((ASSOCQUERY_SDE | 0x1), NULL);
|
||||
ok(hr == S_OK, "QueryExists(DefaultIcon) failed: 0x%08lX\n", hr);
|
||||
|
||||
pElement->Release();
|
||||
}
|
||||
}
|
||||
|
||||
pPS2->Release();
|
||||
}
|
||||
|
||||
|
||||
// A pattern where you create a custom registry source using QuerySourceCreateFromKey
|
||||
// instead of SetString, and attach it directly via IObjectWithQuerySource[Old]::SetSource.
|
||||
static void Test_ShellElement_ExplicitSource(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
if (g_bVistaPlus)
|
||||
{
|
||||
IQuerySource *pSource = NULL;
|
||||
hr = QuerySourceCreateFromKey(HKEY_CLASSES_ROOT, L"txtfile", FALSE,
|
||||
IID_PPV_ARG(IQuerySource, &pSource));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("QuerySourceCreateFromKey(txtfile) failed: 0x%08lX\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
IObjectWithQuerySource *pOWQS = NULL;
|
||||
hr = MyAssocCreateElement(CLSID_AssocShellElement,
|
||||
IID_PPV_ARG(IObjectWithQuerySource, &pOWQS));
|
||||
ok(hr == S_OK, "AssocCreateElement(AssocShellElement) failed: 0x%08lX\n", hr);
|
||||
if (pOWQS)
|
||||
{
|
||||
hr = pOWQS->SetSource(pSource);
|
||||
ok(hr == S_OK, "SetSource failed: 0x%08lX\n", hr);
|
||||
|
||||
IAssociationElement *pElement = NULL;
|
||||
hr = pOWQS->QueryInterface(IID_PPV_ARG(IAssociationElement, &pElement));
|
||||
ok(hr == S_OK, "QI(IAssociationElementOld) failed: 0x%08lX\n", hr);
|
||||
if (pElement)
|
||||
{
|
||||
PWSTR psz = NULL;
|
||||
hr = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok(hr == S_OK, "QueryString(FriendlyTypeName) failed: 0x%08lX\n", hr);
|
||||
if (psz)
|
||||
{
|
||||
trace("txtfile (explicit source) FriendlyTypeName: %s\n",
|
||||
wine_dbgstr_w(psz));
|
||||
CoTaskMemFree(psz);
|
||||
}
|
||||
pElement->Release();
|
||||
}
|
||||
|
||||
// The second call to SetSource should result in E_UNEXPECTED
|
||||
hr = pOWQS->SetSource(pSource);
|
||||
ok_hex(hr, E_UNEXPECTED);
|
||||
|
||||
pOWQS->Release();
|
||||
}
|
||||
|
||||
if (pSource)
|
||||
pSource->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
IQuerySourceOld *pSource = NULL;
|
||||
hr = QuerySourceCreateFromKey(HKEY_CLASSES_ROOT, L"txtfile", FALSE,
|
||||
IID_PPV_ARG(IQuerySourceOld, &pSource));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("QuerySourceCreateFromKey(txtfile) failed: 0x%08lX\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
IObjectWithQuerySourceOld *pOWQS = NULL;
|
||||
hr = MyAssocCreateElement(CLSID_AssocShellElement,
|
||||
IID_PPV_ARG(IObjectWithQuerySourceOld, &pOWQS));
|
||||
ok(hr == S_OK, "AssocCreateElement(AssocShellElement) failed: 0x%08lX\n", hr);
|
||||
if (pOWQS)
|
||||
{
|
||||
hr = pOWQS->SetSource(pSource);
|
||||
ok(hr == S_OK, "SetSource failed: 0x%08lX\n", hr);
|
||||
|
||||
IAssociationElementOld *pElement = NULL;
|
||||
hr = pOWQS->QueryInterface(IID_PPV_ARG(IAssociationElementOld, &pElement));
|
||||
ok(hr == S_OK, "QI(IAssociationElementOld) failed: 0x%08lX\n", hr);
|
||||
if (pElement)
|
||||
{
|
||||
PWSTR psz = NULL;
|
||||
hr = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok(hr == S_OK, "QueryString(FriendlyTypeName) failed: 0x%08lX\n", hr);
|
||||
if (psz)
|
||||
{
|
||||
trace("txtfile (explicit source) FriendlyTypeName: %s\n",
|
||||
wine_dbgstr_w(psz));
|
||||
CoTaskMemFree(psz);
|
||||
}
|
||||
pElement->Release();
|
||||
}
|
||||
|
||||
// The second call to SetSource should result in E_UNEXPECTED
|
||||
hr = pOWQS->SetSource(pSource);
|
||||
ok_hex(hr, E_UNEXPECTED);
|
||||
|
||||
pOWQS->Release();
|
||||
}
|
||||
|
||||
if (pSource)
|
||||
pSource->Release();
|
||||
}
|
||||
}
|
||||
|
||||
// Verify resolution from the file extension using CLSID_AssocProgidElement + SetString(L".txt")
|
||||
static void Test_ProgidElement_DotTxt(void)
|
||||
{
|
||||
IPersistString2 *pPS2 = NULL;
|
||||
HRESULT hr = MyAssocCreateElement(CLSID_AssocProgidElement,
|
||||
IID_PPV_ARG(IPersistString2, &pPS2));
|
||||
ok(hr == S_OK, "AssocCreateElement(AssocProgidElement) failed: 0x%08lX\n", hr);
|
||||
if (!pPS2)
|
||||
return;
|
||||
|
||||
hr = pPS2->SetString(L".txt");
|
||||
ok(hr == S_OK || hr == S_FALSE, "SetString(.txt) failed: 0x%08lX\n", hr);
|
||||
|
||||
if (g_bVistaPlus)
|
||||
{
|
||||
IAssociationElement *pElement = NULL;
|
||||
HRESULT hr2 = pPS2->QueryInterface(IID_PPV_ARG(IAssociationElement, &pElement));
|
||||
ok(hr2 == S_OK, "QI(IAssociationElement) failed: 0x%08lX\n", hr2);
|
||||
if (pElement)
|
||||
pElement->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
IAssociationElementOld *pElement = NULL;
|
||||
HRESULT hr2 = pPS2->QueryInterface(IID_PPV_ARG(IAssociationElementOld, &pElement));
|
||||
ok(hr2 == S_OK, "QI(IAssociationElementOld) failed: 0x%08lX\n", hr2);
|
||||
if (pElement)
|
||||
{
|
||||
PWSTR psz = NULL;
|
||||
HRESULT hr3 = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok(hr3 == S_OK, "QueryString(FriendlyTypeName) for .txt failed: 0x%08lX\n", hr3);
|
||||
if (psz)
|
||||
{
|
||||
trace(".txt FriendlyTypeName: %s\n", wine_dbgstr_w(psz));
|
||||
CoTaskMemFree(psz);
|
||||
}
|
||||
pElement->Release();
|
||||
}
|
||||
}
|
||||
|
||||
pPS2->Release();
|
||||
}
|
||||
|
||||
// CLSID_AssocStarElement: Verify that the generic "File" name can be retrieved even for
|
||||
// unknown file extensions
|
||||
static void Test_StarElement_UnknownExt(void)
|
||||
{
|
||||
IPersistString2 *pPS2 = NULL;
|
||||
HRESULT hr = MyAssocCreateElement(CLSID_AssocStarElement,
|
||||
IID_PPV_ARG(IPersistString2, &pPS2));
|
||||
ok(hr == S_OK, "AssocCreateElement(AssocStarElement) failed: 0x%08lX\n", hr);
|
||||
if (!pPS2)
|
||||
return;
|
||||
|
||||
hr = pPS2->SetString(L".rostestunknownext");
|
||||
ok(hr == S_OK, "SetString failed: 0x%08lX\n", hr);
|
||||
|
||||
if (g_bVistaPlus)
|
||||
{
|
||||
IAssociationElement *pElement = NULL;
|
||||
HRESULT hr2 = pPS2->QueryInterface(IID_PPV_ARG(IAssociationElement, &pElement));
|
||||
ok(hr2 == S_OK, "QI(IAssociationElement) failed: 0x%08lX\n", hr2);
|
||||
if (pElement)
|
||||
{
|
||||
PWSTR psz = NULL;
|
||||
HRESULT hr3 = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok(hr3 == S_OK, "QueryString for unknown extension failed: 0x%08lX\n", hr3);
|
||||
ok(psz != NULL && psz[0] != UNICODE_NULL, "Generic type name is empty\n");
|
||||
if (psz)
|
||||
{
|
||||
trace("Generic file type name: %s\n", wine_dbgstr_w(psz));
|
||||
CoTaskMemFree(psz);
|
||||
}
|
||||
pElement->Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IAssociationElementOld *pElement = NULL;
|
||||
HRESULT hr2 = pPS2->QueryInterface(IID_PPV_ARG(IAssociationElementOld, &pElement));
|
||||
ok(hr2 == S_OK, "QI(IAssociationElementOld) failed: 0x%08lX\n", hr2);
|
||||
if (pElement)
|
||||
{
|
||||
PWSTR psz = NULL;
|
||||
HRESULT hr3 = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok(hr3 == S_OK, "QueryString for unknown extension failed: 0x%08lX\n", hr3);
|
||||
ok(psz != NULL && psz[0] != UNICODE_NULL, "Generic type name is empty\n");
|
||||
if (psz)
|
||||
{
|
||||
trace("Generic file type name: %s\n", wine_dbgstr_w(psz));
|
||||
CoTaskMemFree(psz);
|
||||
}
|
||||
pElement->Release();
|
||||
}
|
||||
}
|
||||
|
||||
pPS2->Release();
|
||||
}
|
||||
|
||||
// CLSID_AssocFolderElement: Always opens HKCR\Folder
|
||||
static void Test_FolderElement(void)
|
||||
{
|
||||
IPersistString2 *pPS2 = NULL;
|
||||
HRESULT hr = MyAssocCreateElement(CLSID_AssocFolderElement,
|
||||
IID_PPV_ARG(IPersistString2, &pPS2));
|
||||
ok(hr == S_OK, "AssocCreateElement(AssocFolderElement) failed: 0x%08lX\n", hr);
|
||||
if (!pPS2)
|
||||
return;
|
||||
|
||||
hr = pPS2->SetString(L"");
|
||||
if (g_bVistaPlus)
|
||||
ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), "SetString hr: 0x%08lX\n", hr);
|
||||
else
|
||||
ok(hr == S_OK, "SetString failed: 0x%08lX\n", hr);
|
||||
|
||||
if (g_bVistaPlus)
|
||||
{
|
||||
IAssociationElement *pElement = NULL;
|
||||
HRESULT hr2 = pPS2->QueryInterface(IID_PPV_ARG(IAssociationElement, &pElement));
|
||||
ok(hr2 == S_OK, "QI(IAssociationElement) failed: 0x%08lX\n", hr2);
|
||||
if (pElement)
|
||||
{
|
||||
PWSTR psz = NULL;
|
||||
HRESULT hr3 = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok(hr3 == S_OK, "QueryString(Folder) failed: 0x%08lX\n", hr3);
|
||||
if (psz)
|
||||
{
|
||||
trace("Folder type name: %s\n", wine_dbgstr_w(psz));
|
||||
CoTaskMemFree(psz);
|
||||
}
|
||||
pElement->Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IAssociationElementOld *pElement = NULL;
|
||||
HRESULT hr2 = pPS2->QueryInterface(IID_PPV_ARG(IAssociationElementOld, &pElement));
|
||||
ok(hr2 == S_OK, "QI(IAssociationElementOld) failed: 0x%08lX\n", hr2);
|
||||
if (pElement)
|
||||
{
|
||||
PWSTR psz = NULL;
|
||||
HRESULT hr3 = pElement->QueryString(ASSOCQUERY_SDEI, NULL, &psz);
|
||||
ok(hr3 == S_OK, "QueryString(Folder) failed: 0x%08lX\n", hr3);
|
||||
if (psz)
|
||||
{
|
||||
trace("Folder type name: %s\n", wine_dbgstr_w(psz));
|
||||
CoTaskMemFree(psz);
|
||||
}
|
||||
pElement->Release();
|
||||
}
|
||||
}
|
||||
|
||||
pPS2->Release();
|
||||
}
|
||||
|
||||
START_TEST(AssocCreateElement)
|
||||
{
|
||||
g_bVistaPlus = IsWindowsVistaOrGreater();
|
||||
|
||||
HINSTANCE hShell32 = GetModuleHandleW(L"shell32.dll");
|
||||
g_fnAssocCreateElement =
|
||||
(FN_AssocCreateElement)GetProcAddress(hShell32, MAKEINTRESOURCEA(764));
|
||||
if (!g_fnAssocCreateElement)
|
||||
trace("shell32!AssocCreateElement not found. Using shlwapi!AssocCreate instead...\n");
|
||||
|
||||
HRESULT hrCo = CoInitialize(NULL);
|
||||
|
||||
Test_InvalidClsid();
|
||||
Test_QueryInterfaceAndClassID();
|
||||
Test_QueryBeforeInit();
|
||||
Test_DoubleSetString();
|
||||
Test_ShellElement_txtfile();
|
||||
Test_ShellElement_ExplicitSource();
|
||||
Test_ProgidElement_DotTxt();
|
||||
Test_StarElement_UnknownExt();
|
||||
Test_FolderElement();
|
||||
|
||||
if (SUCCEEDED(hrCo))
|
||||
CoUninitialize();
|
||||
}
|
||||
@@ -3,6 +3,7 @@ spec2def(shell32_apitest.exe shell32_apitest.spec)
|
||||
|
||||
list(APPEND SOURCE
|
||||
AddCommas.cpp
|
||||
AssocCreateElement.cpp
|
||||
CFSFolder.cpp
|
||||
CheckEscapes.cpp
|
||||
CIDLData.cpp
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <wine/test.h>
|
||||
|
||||
extern void func_AddCommas(void);
|
||||
extern void func_AssocCreateElement(void);
|
||||
extern void func_Control_RunDLLW(void);
|
||||
extern void func_CFSFolder(void);
|
||||
extern void func_CheckEscapes(void);
|
||||
@@ -64,6 +65,7 @@ extern void func_StrRStr(void);
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "AddCommas", func_AddCommas },
|
||||
{ "AssocCreateElement", func_AssocCreateElement },
|
||||
{ "Control_RunDLLW", func_Control_RunDLLW },
|
||||
{ "CFSFolder", func_CFSFolder },
|
||||
{ "CheckEscapes", func_CheckEscapes },
|
||||
|
||||
@@ -999,12 +999,22 @@ LWSTDAPI AssocCreate(_In_ CLSID, _In_ REFIID, _Outptr_ LPVOID*);
|
||||
LWSTDAPI_(BOOL) AssocIsDangerous(_In_ LPCWSTR);
|
||||
#endif // _WIN32_IE_IE60SP1
|
||||
|
||||
typedef INT PERCEIVEDFLAG;
|
||||
#define PERCEIVEDFLAG_UNDEFINED 0x0000
|
||||
#define PERCEIVEDFLAG_SOFTCODED 0x0001
|
||||
#define PERCEIVEDFLAG_HARDCODED 0x0002
|
||||
#define PERCEIVEDFLAG_NATIVESUPPORT 0x0004
|
||||
#define PERCEIVEDFLAG_GDIPLUS 0x0010
|
||||
#define PERCEIVEDFLAG_WMSDK 0x0020
|
||||
#define PERCEIVEDFLAG_ZIPFOLDER 0x0040
|
||||
|
||||
LWSTDAPI AssocQueryStringA(_In_ ASSOCF, _In_ ASSOCSTR, _In_ LPCSTR, _In_opt_ LPCSTR, _Out_writes_opt_(*pcchOut) LPSTR, _Inout_ LPDWORD pcchOut);
|
||||
LWSTDAPI AssocQueryStringW(_In_ ASSOCF, _In_ ASSOCSTR, _In_ LPCWSTR, _In_opt_ LPCWSTR, _Out_writes_opt_(*pcchOut) LPWSTR, _Inout_ LPDWORD pcchOut);
|
||||
LWSTDAPI AssocQueryStringByKeyA(_In_ ASSOCF, _In_ ASSOCSTR, _In_ HKEY, _In_opt_ LPCSTR, _Out_writes_opt_(*pcchOut) LPSTR, _Inout_ LPDWORD pcchOut);
|
||||
LWSTDAPI AssocQueryStringByKeyW(_In_ ASSOCF, _In_ ASSOCSTR, _In_ HKEY, _In_opt_ LPCWSTR, _Out_writes_opt_(*pcchOut) LPWSTR, _Inout_ LPDWORD pcchOut);
|
||||
LWSTDAPI AssocQueryKeyA(_In_ ASSOCF, _In_ ASSOCKEY, _In_ LPCSTR, _In_opt_ LPCSTR, _Out_ PHKEY);
|
||||
LWSTDAPI AssocQueryKeyW(_In_ ASSOCF, _In_ ASSOCKEY, _In_ LPCWSTR, _In_opt_ LPCWSTR, _Out_ PHKEY);
|
||||
LWSTDAPI AssocGetPerceivedType(LPCWSTR lpszExt, PERCEIVED *lpType, INT *lpFlag, LPWSTR *lppszType);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define AssocQueryString AssocQueryStringW
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Shell
|
||||
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
|
||||
* PURPOSE: SHEvaluateSystemCommandTemplate
|
||||
* COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ <[email protected]>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
HRESULT _PathCopyExeAndTrimWhiteSpaces(PWSTR pszBuff, size_t cchBuff,
|
||||
PCWSTR pszSrc, size_t cchSrc);
|
||||
HRESULT _PathFindInFolder(_In_ INT csidl, _In_ PCWSTR pszSrc, _Out_ PWSTR pszPath,
|
||||
_In_ UINT cchPath);
|
||||
HRESULT _PathFindInSystem(_Inout_ PWSTR pszPath, _In_ UINT cchPath);
|
||||
|
||||
HRESULT WINAPI
|
||||
AssocCreateElement(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ PVOID* ppvObj);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
@@ -220,6 +220,16 @@ DEFINE_GUID(POLID_CompareJunctionness, 0xB3AB7D3B, 0x698F, 0x401E,
|
||||
DEFINE_GUID(IID_IObjectWithRegistryKeyOld, 0x5747C63F, 0x1DE8, 0x423F, 0x98, 0x0F, 0x00, 0xCB, 0x07, 0xF4, 0xC4, 0x5B);
|
||||
DEFINE_GUID(IID_IObjectWithRegistryKey, 0xD960050C, 0xF4E1, 0x4294, 0xAC, 0x4B, 0x59, 0x89, 0x13, 0x60, 0x59, 0x23);
|
||||
|
||||
DEFINE_GUID(CLSID_AssocApplicationElement, 0x0C2BF91B, 0x8746, 0x4FB1, 0xB4, 0xD7, 0x7C, 0x03, 0xF8, 0x90, 0xB1, 0x68);
|
||||
DEFINE_GUID(CLSID_AssocClientElement, 0x3C81E7FA, 0x1F3B, 0x464A, 0xA3, 0x50, 0x11, 0x4A, 0x25, 0xBE, 0xB2, 0xA2);
|
||||
DEFINE_GUID(CLSID_AssocClsidElement, 0x57AEA081, 0x5EE9, 0x4C27, 0xB2, 0x18, 0xC4, 0xB7, 0x02, 0x96, 0x4C, 0x54);
|
||||
DEFINE_GUID(CLSID_AssocFolderElement, 0x7566DF7A, 0x42CC, 0x475D, 0xA0, 0x25, 0x12, 0x05, 0xDD, 0xF4, 0x91, 0x1F);
|
||||
DEFINE_GUID(CLSID_AssocPerceivedElement, 0x0DC5FB21, 0xB93D, 0x4E3D, 0xBB, 0x2F, 0xCE, 0x4E, 0x36, 0xA7, 0x06, 0x01);
|
||||
DEFINE_GUID(CLSID_AssocProgidElement, 0x9016D0DD, 0x7C41, 0x46CC, 0xA6, 0x64, 0xBF, 0x22, 0xF7, 0xCB, 0x18, 0x6A);
|
||||
DEFINE_GUID(CLSID_AssocShellElement, 0xC461837F, 0xEA59, 0x494A, 0xB7, 0xC6, 0xCD, 0x04, 0x0E, 0x37, 0x18, 0x5E);
|
||||
DEFINE_GUID(CLSID_AssocStarElement, 0x0633B720, 0x6926, 0x404C, 0xB6, 0xB3, 0x92, 0x3B, 0x1A, 0x50, 0x17, 0x43);
|
||||
DEFINE_GUID(CLSID_AssocSystemElement, 0xA6C4BAAD, 0x4AF5, 0x4191, 0x86, 0x85, 0xC2, 0xC8, 0x95, 0x3A, 0x14, 0x8C);
|
||||
|
||||
#define CGID_IExplorerToolbar IID_IExplorerToolbar
|
||||
#define SID_IExplorerToolbar IID_IExplorerToolbar
|
||||
#define SID_ITargetFrame2 IID_ITargetFrame2
|
||||
@@ -231,4 +241,6 @@ DEFINE_GUID(IID_IObjectWithRegistryKey, 0xD960050C, 0xF4E1, 0x4294,
|
||||
#define SID_IBandSite IID_IBandSite
|
||||
#define SID_IShellBrowser IID_IShellBrowser
|
||||
|
||||
#define IID_IObjectWithQuerySourceOld IID_IObjectWithQuerySource
|
||||
|
||||
#endif // __SHLGUID_UNDOC_H
|
||||
|
||||
@@ -946,9 +946,37 @@ DECLARE_INTERFACE_(IQuerySource, IUnknown) // {7BC28AC2-0D9C-4941-BB9A-72BECB184
|
||||
#define IQuerySource_OpenSource(T,a,b) (T)->lpVtbl->OpenSource(T,a,b)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* IObjectWithQuerySourceOld interface
|
||||
*
|
||||
* @see IObjectWithQuerySource
|
||||
* @see https://www.geoffchappell.com/studies/windows/shell/shell32/interfaces/iobjectwithquerysource.htm
|
||||
*/
|
||||
#define INTERFACE IObjectWithQuerySourceOld
|
||||
DECLARE_INTERFACE_(IObjectWithQuerySourceOld, IUnknown) // {B3DCB623-4280-4EB1-84B3-8D07E84F299A}
|
||||
{
|
||||
/*** IUnknown ***/
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** IObjectWithQuerySourceOld ***/
|
||||
STDMETHOD(SetSource)(THIS_ IQuerySourceOld *pSource) PURE;
|
||||
STDMETHOD(GetSource)(THIS_ REFIID riid, PVOID *ppSource) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#ifdef COBJMACROS
|
||||
#define IObjectWithQuerySourceOld_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b)
|
||||
#define IObjectWithQuerySourceOld_AddRef(T) (T)->lpVtbl->AddRef(T)
|
||||
#define IObjectWithQuerySourceOld_Release(T) (T)->lpVtbl->Release(T)
|
||||
#define IObjectWithQuerySourceOld_SetSource(T,a) (T)->lpVtbl->SetSource(T,a)
|
||||
#define IObjectWithQuerySourceOld_GetSource(T,a,b) (T)->lpVtbl->GetSource(T,a,b)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* IObjectWithQuerySource interface
|
||||
*
|
||||
* @see IObjectWithQuerySourceOld
|
||||
* @see https://www.geoffchappell.com/studies/windows/shell/shell32/interfaces/iobjectwithquerysource.htm
|
||||
*/
|
||||
#define INTERFACE IObjectWithQuerySource
|
||||
|
||||
@@ -358,6 +358,10 @@ enum _shellkey_flags
|
||||
};
|
||||
|
||||
HKEY WINAPI SHGetShellKey(DWORD flags, LPCWSTR sub_key, BOOL create);
|
||||
HRESULT WINAPI SKGetValueW(DWORD flags, LPCWSTR subkey, LPCWSTR value, DWORD *type,
|
||||
void *data, DWORD *count);
|
||||
HRESULT WINAPI SKSetValueW(DWORD flags, LPCWSTR subkey, LPCWSTR value,
|
||||
DWORD type, void *data, DWORD count);
|
||||
|
||||
int
|
||||
WINAPIV
|
||||
@@ -561,6 +565,11 @@ SHWindowsPolicyEx(_In_ REFGUID rpolid, _In_ DWORD dwDefaultValue)
|
||||
return (SUCCEEDED(hr) ? dwData : dwDefaultValue);
|
||||
}
|
||||
|
||||
#if (NTDDI_VERSION >= NTDDI_LONGHORN) || defined(_SHELL32_)
|
||||
HRESULT WINAPI
|
||||
AssocCreateElement(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ PVOID* ppvObj);
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* ZoneCheck*
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user