mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
[SHLWAPI][SHLWAPI_APITEST][SDK] Support QuerySourceCreateFromKey (#9093)
Implementing missing features... JIRA issue: CORE-20467 - Add querysrc.cpp. - Add CRegistryEnumValues, CRegistryEnumKeys, and CRegistrySource classes. - Implement QuerySourceCreateFromKey function. - Add prototype into <shlwapi_undoc.h>. - Modify shlwapi.spec. - Add QuerySourceCreateFromKey testcase.
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Tests for QuerySourceCreateFromKey
|
||||
* COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ <[email protected]>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <shlguid_undoc.h>
|
||||
#include <shlobj_undoc.h>
|
||||
#include <shlwapi_undoc.h>
|
||||
#include <versionhelpers.h>
|
||||
|
||||
typedef HRESULT (WINAPI *FN_QuerySourceCreateFromKey)(HKEY, PCWSTR, BOOL, REFIID, PVOID*);
|
||||
static FN_QuerySourceCreateFromKey g_pQuerySourceCreateFromKey = NULL;
|
||||
|
||||
static const WCHAR k_Root[] = L"Software\\QuerySrcTest";
|
||||
static const WCHAR k_SubKeyA[] = L"SubKeyA";
|
||||
static const WCHAR k_SubKeyB[] = L"SubKeyB";
|
||||
|
||||
static void SetupRegistry(void)
|
||||
{
|
||||
HKEY hRoot;
|
||||
RegCreateKeyExW(HKEY_CURRENT_USER, k_Root, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hRoot, NULL);
|
||||
|
||||
static const WCHAR valA[] = L"hello";
|
||||
RegSetValueExW(hRoot, L"ValueA", 0, REG_SZ, (const BYTE*)valA, (DWORD)sizeof(valA));
|
||||
|
||||
DWORD dwValue = 0xBEEFCAFE;
|
||||
RegSetValueExW(hRoot, L"ValueB", 0, REG_DWORD, (const BYTE*)&dwValue, (DWORD)sizeof(dwValue));
|
||||
|
||||
HKEY hSub;
|
||||
RegCreateKeyExW(hRoot, k_SubKeyA, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hSub, NULL);
|
||||
RegCloseKey(hSub);
|
||||
RegCreateKeyExW(hRoot, k_SubKeyB, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hSub, NULL);
|
||||
RegCloseKey(hSub);
|
||||
|
||||
RegCloseKey(hRoot);
|
||||
}
|
||||
|
||||
static void CleanupRegistry(void)
|
||||
{
|
||||
SHDeleteKeyW(HKEY_CURRENT_USER, k_Root);
|
||||
}
|
||||
|
||||
static void Test_EnumValues(void)
|
||||
{
|
||||
IQuerySourceOld *pSrc = NULL;
|
||||
HRESULT hr = g_pQuerySourceCreateFromKey(HKEY_CURRENT_USER, k_Root, FALSE,
|
||||
IID_IQuerySourceOld, (PVOID*)&pSrc);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(pSrc != NULL, "pSrc was NULL\n");
|
||||
|
||||
IEnumString *pEnum = NULL;
|
||||
hr = 0xDEADFACE;
|
||||
if (pSrc)
|
||||
hr = pSrc->EnumValues(&pEnum);
|
||||
ok(pSrc && hr == S_OK, "EnumValues failed: 0x%08X\n", hr);
|
||||
|
||||
LPWSTR psz = NULL;
|
||||
ULONG fetched = 0;
|
||||
hr = 0xDEADFACE;
|
||||
|
||||
if (pEnum)
|
||||
hr = pEnum->Next(1, &psz, &fetched);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(lstrcmpiW(psz, L"ValueA") == 0, "psz was %s\n", wine_dbgstr_w(psz));
|
||||
ok_int(fetched, 1);
|
||||
CoTaskMemFree(psz);
|
||||
|
||||
psz = NULL;
|
||||
fetched = 0;
|
||||
hr = 0xDEADFACE;
|
||||
|
||||
if (pEnum)
|
||||
hr = pEnum->Next(1, &psz, &fetched);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(lstrcmpiW(psz, L"ValueB") == 0, "psz was %s\n", wine_dbgstr_w(psz));
|
||||
ok_int(fetched, 1);
|
||||
CoTaskMemFree(psz);
|
||||
|
||||
psz = NULL;
|
||||
fetched = 0;
|
||||
hr = 0xDEADFACE;
|
||||
|
||||
if (pEnum)
|
||||
hr = pEnum->Next(1, &psz, &fetched);
|
||||
ok_hr(hr, S_FALSE);
|
||||
ok(psz == NULL, "psz was %s\n", wine_dbgstr_w(psz));
|
||||
ok_int(fetched, 0);
|
||||
CoTaskMemFree(psz);
|
||||
|
||||
if (pEnum)
|
||||
pEnum->Release();
|
||||
if (pSrc)
|
||||
pSrc->Release();
|
||||
}
|
||||
|
||||
static void Test_EnumSources(void)
|
||||
{
|
||||
IQuerySourceOld *pSrc = NULL;
|
||||
HRESULT hr = g_pQuerySourceCreateFromKey(HKEY_CURRENT_USER, k_Root, FALSE,
|
||||
IID_IQuerySourceOld, (PVOID*)&pSrc);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(pSrc != NULL, "pSrc was NULL\n");
|
||||
|
||||
IEnumString *pEnum = NULL;
|
||||
hr = pSrc->EnumSources(&pEnum);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(pEnum != NULL, "pEnum was NULL\n");
|
||||
|
||||
LPWSTR psz = NULL;
|
||||
ULONG fetched = 0;
|
||||
hr = 0xDEADFACE;
|
||||
|
||||
if (pEnum)
|
||||
hr = pEnum->Next(1, &psz, &fetched);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(lstrcmpiW(psz, k_SubKeyA) == 0, "psz was %s\n", wine_dbgstr_w(psz));
|
||||
ok_int(fetched, 1);
|
||||
CoTaskMemFree(psz);
|
||||
|
||||
psz = NULL;
|
||||
fetched = 0;
|
||||
hr = 0xDEADFACE;
|
||||
|
||||
if (pEnum)
|
||||
hr = pEnum->Next(1, &psz, &fetched);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(lstrcmpiW(psz, k_SubKeyB) == 0, "psz was %s\n", wine_dbgstr_w(psz));
|
||||
ok_int(fetched, 1);
|
||||
CoTaskMemFree(psz);
|
||||
|
||||
psz = NULL;
|
||||
fetched = 0;
|
||||
hr = 0xDEADFACE;
|
||||
|
||||
if (pEnum)
|
||||
hr = pEnum->Next(1, &psz, &fetched);
|
||||
ok_hr(hr, S_FALSE);
|
||||
ok(psz == NULL, "psz was %s\n", wine_dbgstr_w(psz));
|
||||
ok_int(fetched, 0);
|
||||
CoTaskMemFree(psz);
|
||||
|
||||
if (pSrc)
|
||||
pSrc->Release();
|
||||
}
|
||||
|
||||
static void Test_CheckValues(void)
|
||||
{
|
||||
IQuerySourceOld *pSrc = NULL;
|
||||
HRESULT hr = g_pQuerySourceCreateFromKey(HKEY_CURRENT_USER, k_Root, FALSE,
|
||||
IID_IQuerySourceOld, (PVOID*)&pSrc);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(pSrc != NULL, "pSrc was NULL\n");
|
||||
|
||||
PWSTR pszValue;
|
||||
|
||||
// QueryValueString
|
||||
hr = 0xDEADFACE;
|
||||
pszValue = NULL;
|
||||
if (pSrc)
|
||||
hr = pSrc->QueryValueString(NULL, L"ValueA", &pszValue);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(lstrcmpiW(pszValue, L"hello") == 0, "pszValue was %s\n", wine_dbgstr_w(pszValue));
|
||||
|
||||
hr = 0xDEADFACE;
|
||||
pszValue = NULL;
|
||||
if (pSrc)
|
||||
hr = pSrc->QueryValueString(NULL, L"ValueB", &pszValue);
|
||||
ok_hr(hr, E_DATATYPE_MISMATCH);
|
||||
ok(pszValue == NULL, "pszValue was %s\n", wine_dbgstr_w(pszValue));
|
||||
|
||||
// QueryValueExists
|
||||
hr = 0xDEADFACE;
|
||||
if (pSrc)
|
||||
hr = pSrc->QueryValueExists(NULL, L"ValueA");
|
||||
ok_hr(hr, S_OK);
|
||||
if (pSrc)
|
||||
hr = pSrc->QueryValueExists(NULL, L"ValueB");
|
||||
ok_hr(hr, S_OK);
|
||||
|
||||
DWORD dwValue;
|
||||
|
||||
// QueryValueDword
|
||||
dwValue = 0xDEADFACE;
|
||||
hr = 0xDEADFACE;
|
||||
if (pSrc)
|
||||
hr = pSrc->QueryValueDword(NULL, L"ValueA", &dwValue);
|
||||
ok_hr(hr, HRESULT_FROM_WIN32(ERROR_MORE_DATA));
|
||||
ok_long(dwValue, 0xDEADFACE);
|
||||
|
||||
dwValue = 0xDEADFACE;
|
||||
hr = 0xDEADFACE;
|
||||
if (pSrc)
|
||||
hr = pSrc->QueryValueDword(NULL, L"ValueB", &dwValue);
|
||||
ok_hr(hr, S_OK);
|
||||
ok_long(dwValue, 0xBEEFCAFE);
|
||||
|
||||
FLAGGED_BYTE_BLOB *pBlob;
|
||||
|
||||
// QueryValueDirect
|
||||
hr = 0xDEADFACE;
|
||||
pBlob = NULL;
|
||||
if (pSrc)
|
||||
hr = pSrc->QueryValueDirect(NULL, L"ValueA", &pBlob);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(pBlob != NULL, "pBlob was %p\n", pBlob);
|
||||
ok(pBlob && pBlob->clSize == 12, "pBlob->clSize was %ld\n", pBlob->clSize);
|
||||
ok(pBlob && !memcmp(pBlob->abData, L"hello", 12), "pBlob->abData mismatch\n");
|
||||
CoTaskMemFree(pBlob);
|
||||
|
||||
hr = 0xDEADFACE;
|
||||
pBlob = NULL;
|
||||
if (pSrc)
|
||||
hr = pSrc->QueryValueDirect(NULL, L"ValueB", &pBlob);
|
||||
ok_hr(hr, S_OK);
|
||||
ok(pBlob != NULL, "pBlob was %p\n", pBlob);
|
||||
ok(pBlob && pBlob->clSize == 4, "pBlob->clSize was %ld\n", pBlob->clSize);
|
||||
dwValue = 0xBEEFCAFE;
|
||||
ok(pBlob && !memcmp(pBlob->abData, &dwValue, sizeof(dwValue)), "pBlob->abData mismatch\n");
|
||||
CoTaskMemFree(pBlob);
|
||||
|
||||
if (pSrc)
|
||||
pSrc->Release();
|
||||
}
|
||||
|
||||
START_TEST(QuerySourceCreateFromKey)
|
||||
{
|
||||
if (IsWindowsVistaOrGreater())
|
||||
{
|
||||
skip("Vista+ is not tested well\n");
|
||||
return;
|
||||
}
|
||||
|
||||
g_pQuerySourceCreateFromKey = (FN_QuerySourceCreateFromKey)
|
||||
GetProcAddress(GetModuleHandleA("shlwapi"), MAKEINTRESOURCEA(544));
|
||||
if (!g_pQuerySourceCreateFromKey)
|
||||
{
|
||||
skip("QuerySourceCreateFromKey not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hrCoInit = CoInitialize(NULL);
|
||||
|
||||
SetupRegistry();
|
||||
|
||||
Test_EnumValues();
|
||||
Test_EnumSources();
|
||||
Test_CheckValues();
|
||||
|
||||
CleanupRegistry();
|
||||
|
||||
if (SUCCEEDED(hrCoInit))
|
||||
CoUninitialize();
|
||||
}
|
||||
Reference in New Issue
Block a user