diff --git a/modules/rostests/apitests/shlwapi/AssocQueryString.c b/modules/rostests/apitests/shlwapi/AssocQueryString.c new file mode 100644 index 00000000000..ccf6ec1c91b --- /dev/null +++ b/modules/rostests/apitests/shlwapi/AssocQueryString.c @@ -0,0 +1,187 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later) + * PURPOSE: Test for AssocQueryStringA/W + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include +#include +#include +#include + +typedef HRESULT (WINAPI *FN_AssocQueryStringA)( + ASSOCF cfFlags, + ASSOCSTR str, + LPCSTR pszAssoc, + LPCSTR pszExtra, + LPSTR pszOut, + DWORD *pcchOut); +typedef HRESULT (WINAPI *FN_AssocQueryStringW)( + ASSOCF cfFlags, + ASSOCSTR str, + LPCWSTR pszAssoc, + LPCWSTR pszExtra, + LPWSTR pszOut, + DWORD *pcchOut); + +static HINSTANCE s_hSHLWAPI = NULL; +static FN_AssocQueryStringA s_fnAssocQueryStringA = NULL; +static FN_AssocQueryStringW s_fnAssocQueryStringW = NULL; +static CHAR s_szTextFileA[MAX_PATH] = ""; +static WCHAR s_szTextFileW[MAX_PATH] = L""; +#define NON_EXISTENT_FILENAME_A "C:\\ThisIsNotExistentFile.txt" +#define NON_EXISTENT_FILENAME_W L"C:\\ThisIsNotExistentFile.txt" + +static void TEST_Start(void) +{ + ExpandEnvironmentStringsA( "%APPDATA%\\This is a test.txt", s_szTextFileA, _countof(s_szTextFileA)); + ExpandEnvironmentStringsW(L"%APPDATA%\\This is a test.txt", s_szTextFileW, _countof(s_szTextFileW)); + fclose(_wfopen(s_szTextFileW, L"w")); + trace("%s\n", wine_dbgstr_a(s_szTextFileA)); + trace("%s\n", wine_dbgstr_w(s_szTextFileW)); +} + +static void TEST_End(void) +{ + DeleteFileW(s_szTextFileW); +} + +/* + * "shlwapi_winetest assoc" already has many tests. + * We just do additional tests in here. + */ + +static void TEST_AssocQueryStringA(void) +{ + CHAR szPath[MAX_PATH], szAnswer[MAX_PATH]; + CHAR szDebug1[MAX_PATH], szDebug2[MAX_PATH]; + HRESULT hr; + DWORD cch; + + /* ".txt" */ + lstrcpynA(szPath, ".txt", _countof(szPath)); + cch = _countof(szPath); + hr = AssocQueryStringA(0, ASSOCSTR_EXECUTABLE, szPath, NULL, szPath, &cch); + if (IsWindowsVistaOrGreater()) + { + ExpandEnvironmentStringsA("%WINDIR%\\system32\\notepad.exe", szAnswer, _countof(szAnswer)); + ok_long(hr, S_OK); + ok_int(cch, lstrlenA(szAnswer) + 1); + } + else + { + lstrcpynA(szAnswer, ".txt", _countof(szAnswer)); + ok_long(hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); + ok_int(cch, _countof(szPath)); + } + lstrcpynA(szDebug1, wine_dbgstr_a(szPath), _countof(szDebug1)); + lstrcpynA(szDebug2, wine_dbgstr_a(szAnswer), _countof(szDebug2)); + ok(lstrcmpiA(szPath, szAnswer) == 0, "%s vs %s\n", szDebug1, szDebug2); + + /* s_szTextFileA */ + lstrcpynA(szPath, s_szTextFileA, _countof(szPath)); + cch = _countof(szPath); + hr = AssocQueryStringA(0, ASSOCSTR_EXECUTABLE, szPath, NULL, szPath, &cch); + if (IsWindowsVistaOrGreater()) + { + ExpandEnvironmentStringsA("%WINDIR%\\system32\\notepad.exe", szAnswer, _countof(szAnswer)); + ok_long(hr, S_OK); + ok_int(cch, lstrlenA(szAnswer) + 1); + } + else + { + lstrcpynA(szAnswer, s_szTextFileA, _countof(szAnswer)); + ok_long(hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); + ok_int(cch, _countof(szPath)); + } + lstrcpynA(szDebug1, wine_dbgstr_a(szPath), _countof(szDebug1)); + lstrcpynA(szDebug2, wine_dbgstr_a(szAnswer), _countof(szDebug2)); + ok(lstrcmpiA(szPath, szAnswer) == 0, "%s vs %s\n", szDebug1, szDebug2); + + /* NON_EXISTENT_FILENAME_A */ + lstrcpynA(szPath, NON_EXISTENT_FILENAME_A, _countof(szPath)); + cch = _countof(szPath); + hr = AssocQueryStringA(0, ASSOCSTR_EXECUTABLE, szPath, NULL, szPath, &cch); + if (IsWindowsVistaOrGreater()) + { + ExpandEnvironmentStringsA("%WINDIR%\\system32\\notepad.exe", szAnswer, _countof(szAnswer)); + ok_long(hr, S_OK); + ok_int(cch, lstrlenA(szAnswer) + 1); + } + else + { + lstrcpynA(szAnswer, NON_EXISTENT_FILENAME_A, _countof(szAnswer)); + ok_long(hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); + ok_int(cch, _countof(szPath)); + } + lstrcpynA(szDebug1, wine_dbgstr_a(szPath), _countof(szDebug1)); + lstrcpynA(szDebug2, wine_dbgstr_a(szAnswer), _countof(szDebug2)); + ok(lstrcmpiA(szPath, szAnswer) == 0, "%s vs %s\n", szDebug1, szDebug2); +} + +static void TEST_AssocQueryStringW(void) +{ + WCHAR szPath[MAX_PATH], szAnswer[MAX_PATH]; + CHAR szDebug1[MAX_PATH], szDebug2[MAX_PATH]; + HRESULT hr; + DWORD cch; + + /* ".txt" */ + lstrcpynW(szPath, L".txt", _countof(szPath)); + cch = _countof(szPath); + hr = AssocQueryStringW(0, ASSOCSTR_EXECUTABLE, szPath, NULL, szPath, &cch); + ok_long(hr, S_OK); + ExpandEnvironmentStringsW(L"%WINDIR%\\system32\\notepad.exe", szAnswer, _countof(szAnswer)); + lstrcpynA(szDebug1, wine_dbgstr_w(szPath), _countof(szDebug1)); + lstrcpynA(szDebug2, wine_dbgstr_w(szAnswer), _countof(szDebug2)); + ok(lstrcmpiW(szPath, szAnswer) == 0, "%s vs %s\n", szDebug1, szDebug2); + ok_int(cch, lstrlenW(szAnswer) + 1); + + /* s_szTextFileW */ + lstrcpynW(szPath, s_szTextFileW, _countof(szPath)); + cch = _countof(szPath); + hr = AssocQueryStringW(0, ASSOCSTR_EXECUTABLE, szPath, NULL, szPath, &cch); + ok_long(hr, S_OK); + ExpandEnvironmentStringsW(L"%WINDIR%\\system32\\notepad.exe", szAnswer, _countof(szAnswer)); + lstrcpynA(szDebug1, wine_dbgstr_w(szPath), _countof(szDebug1)); + lstrcpynA(szDebug2, wine_dbgstr_w(szAnswer), _countof(szDebug2)); + ok(lstrcmpiW(szPath, szAnswer) == 0, "%s vs %s\n", szDebug1, szDebug2); + ok_int(cch, lstrlenW(szAnswer) + 1); + + /* NON_EXISTENT_FILENAME_W */ + lstrcpynW(szPath, NON_EXISTENT_FILENAME_W, _countof(szPath)); + cch = _countof(szPath); + hr = AssocQueryStringW(0, ASSOCSTR_EXECUTABLE, szPath, NULL, szPath, &cch); + ok_long(hr, S_OK); + ExpandEnvironmentStringsW(L"%WINDIR%\\system32\\notepad.exe", szAnswer, _countof(szAnswer)); + lstrcpynA(szDebug1, wine_dbgstr_w(szPath), _countof(szDebug1)); + lstrcpynA(szDebug2, wine_dbgstr_w(szAnswer), _countof(szDebug2)); + ok(lstrcmpiW(szPath, szAnswer) == 0, "%s vs %s\n", szDebug1, szDebug2); + ok_int(cch, lstrlenW(szAnswer) + 1); +} + +START_TEST(AssocQueryString) +{ + HRESULT hrCoInit = CoInitialize(NULL); + + s_hSHLWAPI = LoadLibraryW(L"shlwapi.dll"); + s_fnAssocQueryStringA = (FN_AssocQueryStringA)GetProcAddress(s_hSHLWAPI, "AssocQueryStringA"); + s_fnAssocQueryStringW = (FN_AssocQueryStringW)GetProcAddress(s_hSHLWAPI, "AssocQueryStringW"); + if (!s_fnAssocQueryStringA || !s_fnAssocQueryStringW) + { + skip("AssocQueryStringA or AssocQueryStringW not found: %p, %p\n", + s_fnAssocQueryStringA, s_fnAssocQueryStringW); + return; + } + + TEST_Start(); + TEST_AssocQueryStringA(); + TEST_AssocQueryStringW(); + TEST_End(); + + FreeLibrary(s_hSHLWAPI); + + if (SUCCEEDED(hrCoInit)) + CoUninitialize(); +} diff --git a/modules/rostests/apitests/shlwapi/CMakeLists.txt b/modules/rostests/apitests/shlwapi/CMakeLists.txt index adba1083be0..4000fd26775 100644 --- a/modules/rostests/apitests/shlwapi/CMakeLists.txt +++ b/modules/rostests/apitests/shlwapi/CMakeLists.txt @@ -5,6 +5,7 @@ add_subdirectory(shlwapi_resource_dll) include_directories($) list(APPEND SOURCE + AssocQueryString.c PathFindOnPath.c PathIsUNC.c PathIsUNCServer.c diff --git a/modules/rostests/apitests/shlwapi/testlist.c b/modules/rostests/apitests/shlwapi/testlist.c index 9ec57ee2686..b497fc8836a 100644 --- a/modules/rostests/apitests/shlwapi/testlist.c +++ b/modules/rostests/apitests/shlwapi/testlist.c @@ -1,6 +1,7 @@ #define STANDALONE #include +extern void func_AssocQueryString(void); extern void func_PathFindOnPath(void); extern void func_isuncpath(void); extern void func_isuncpathserver(void); @@ -16,6 +17,7 @@ extern void func_StrFormatByteSizeW(void); const struct test winetest_testlist[] = { + { "AssocQueryString", func_AssocQueryString }, { "PathFindOnPath", func_PathFindOnPath }, { "PathIsUNC", func_isuncpath }, { "PathIsUNCServer", func_isuncpathserver },