https://git.reactos.org/?p=reactos.git;a=commitdiff;h=922a956805ab41f26583fb...
commit 922a956805ab41f26583fbd6cc2c7120a01008e1 Author: Mark Jansen mark.jansen@reactos.org AuthorDate: Mon May 18 21:38:56 2020 +0200 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Thu Sep 10 19:45:15 2020 +0200
[SHLWAPI_APITEST] Add test showing SHLoadIndirectString should load a dll as datafile --- modules/rostests/apitests/shlwapi/CMakeLists.txt | 10 ++ .../apitests/shlwapi/SHLoadIndirectString.c | 134 +++++++++++++++++++++ .../shlwapi/shlwapi_resource_dll/CMakeLists.txt | 5 + .../shlwapi_resource_dll/shlwapi_resource_dll.c | 27 +++++ .../shlwapi_resource_dll/shlwapi_resource_dll.rc | 9 ++ modules/rostests/apitests/shlwapi/testdata.rc | 3 + modules/rostests/apitests/shlwapi/testlist.c | 2 + 7 files changed, 190 insertions(+)
diff --git a/modules/rostests/apitests/shlwapi/CMakeLists.txt b/modules/rostests/apitests/shlwapi/CMakeLists.txt index a7d4e05d4fb..9712d77969b 100644 --- a/modules/rostests/apitests/shlwapi/CMakeLists.txt +++ b/modules/rostests/apitests/shlwapi/CMakeLists.txt @@ -1,4 +1,9 @@
+add_subdirectory(shlwapi_resource_dll) + +# Ensure the resource compiler can find the dll +include_directories($<TARGET_FILE_DIR:shlwapi_resource_dll>) + list(APPEND SOURCE PathFindOnPath.c PathIsUNC.c @@ -7,12 +12,17 @@ list(APPEND SOURCE PathUnExpandEnvStrings.c PathUnExpandEnvStringsForUser.c SHAreIconsEqual.c + SHLoadIndirectString.c StrFormatByteSizeW.c testdata.rc testlist.c)
+# Add a dependency from the resource to the dll +add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/shlwapi_resource_dll/shlwapi_resource_dll.dll) + add_executable(shlwapi_apitest ${SOURCE}) set_module_type(shlwapi_apitest win32cui) target_link_libraries(shlwapi_apitest ${PSEH_LIB}) add_importlibs(shlwapi_apitest shlwapi user32 msvcrt kernel32) +add_dependencies(shlwapi_apitest shlwapi_resource_dll) add_rostests_file(TARGET shlwapi_apitest) diff --git a/modules/rostests/apitests/shlwapi/SHLoadIndirectString.c b/modules/rostests/apitests/shlwapi/SHLoadIndirectString.c new file mode 100644 index 00000000000..f086a7e2514 --- /dev/null +++ b/modules/rostests/apitests/shlwapi/SHLoadIndirectString.c @@ -0,0 +1,134 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Tests for SHLoadIndirectString + * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org) + */ + +#include <apitest.h> +#include <shlwapi.h> +#include "resource.h" + +static void execute_test(LPCWSTR DllFile) +{ + WCHAR DllBuffer[MAX_PATH + 20]; + WCHAR Buffer[MAX_PATH * 2] = {0}; + HRESULT hr; + HANDLE hEvent; + DWORD dwRet; + + hEvent = CreateEventA(NULL, TRUE, FALSE, "Local\shlwapi_apitest_evt"); + + // Show that it is not signaled + dwRet = WaitForSingleObject(hEvent, 1); + ok_hex(dwRet, WAIT_TIMEOUT); + + // Ensure the module is not loaded yet... + HMODULE mod = GetModuleHandleW(DllFile); + if (mod != NULL) + { + CloseHandle(hEvent); + skip("%S loaded, cannot continue\n", DllFile); + return; + } + + wsprintfW(DllBuffer, L"@%s,-3", DllFile); + + // Load a string from the dll + hr = SHLoadIndirectString(DllBuffer, Buffer, _countof(Buffer), NULL); + ok_hex(hr, S_OK); + if (SUCCEEDED(hr)) + { + // Module should still not be loaded + mod = GetModuleHandleW(DllFile); + ok_ptr(mod, 0); + + ok_wstr(Buffer, L"Test string one."); + + // DllMain not called.. + dwRet = WaitForSingleObject(hEvent, 1); + ok_hex(dwRet, WAIT_TIMEOUT); + + // Show that calling DllMain will set the event + mod = LoadLibraryW(DllFile); + ok(mod != NULL, "Failed to load %S\n", DllFile); + + if (mod) + { + dwRet = WaitForSingleObject(hEvent, 1); + ok_hex(dwRet, WAIT_OBJECT_0); + FreeLibrary(mod); + } + } + CloseHandle(hEvent); +} + + +BOOL extract_resource(const WCHAR* Filename, LPCWSTR ResourceName) +{ + BOOL Success; + DWORD dwWritten, Size; + HGLOBAL hGlobal; + LPVOID pData; + HANDLE Handle; + HRSRC hRsrc = FindResourceW(GetModuleHandleW(NULL), ResourceName, (LPCWSTR)10); + ok(!!hRsrc, "Unable to find %s\n", wine_dbgstr_w(ResourceName)); + if (!hRsrc) + return FALSE; + + hGlobal = LoadResource(GetModuleHandleW(NULL), hRsrc); + Size = SizeofResource(GetModuleHandleW(NULL), hRsrc); + pData = LockResource(hGlobal); + + ok(Size && !!pData, "Unable to load %s\n", wine_dbgstr_w(ResourceName)); + if (!Size || !pData) + return FALSE; + + Handle = CreateFileW(Filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if (Handle == INVALID_HANDLE_VALUE) + { + skip("Failed to create temp file %ls, error %lu\n", Filename, GetLastError()); + return FALSE; + } + Success = WriteFile(Handle, pData, Size, &dwWritten, NULL); + ok(Success == TRUE, "WriteFile failed with %lu\n", GetLastError()); + ok(dwWritten == Size, "WriteFile wrote %lu bytes instead of %lu\n", dwWritten, Size); + CloseHandle(Handle); + Success = Success && (dwWritten == Size); + + UnlockResource(pData); + return Success; +} + +START_TEST(SHLoadIndirectString) +{ + WCHAR workdir[MAX_PATH], dllpath[MAX_PATH]; + BOOL ret; + UINT Length; + + ret = GetTempPathW(_countof(workdir), workdir); + ok(ret, "GetTempPathW error: %lu\n", GetLastError()); + + Length = GetTempFileNameW(workdir, L"ntdll", 0, dllpath); + ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError()); + + if (extract_resource(dllpath, (LPCWSTR)101)) + { + _SEH2_TRY + { + execute_test(dllpath); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ok(0, "Ldr didnt handle exception\n"); + } + _SEH2_END; + } + else + { + ok(0, "Failed to extract resource\n"); + } + + DeleteFileW(dllpath); +} diff --git a/modules/rostests/apitests/shlwapi/shlwapi_resource_dll/CMakeLists.txt b/modules/rostests/apitests/shlwapi/shlwapi_resource_dll/CMakeLists.txt new file mode 100644 index 00000000000..800dcb41fa8 --- /dev/null +++ b/modules/rostests/apitests/shlwapi/shlwapi_resource_dll/CMakeLists.txt @@ -0,0 +1,5 @@ + +add_library(shlwapi_resource_dll MODULE shlwapi_resource_dll.c shlwapi_resource_dll.rc) +set_module_type(shlwapi_resource_dll win32dll ENTRYPOINT DllMain 12) +add_importlibs(shlwapi_resource_dll kernel32 ntdll) +add_dependencies(shlwapi_resource_dll psdk) diff --git a/modules/rostests/apitests/shlwapi/shlwapi_resource_dll/shlwapi_resource_dll.c b/modules/rostests/apitests/shlwapi/shlwapi_resource_dll/shlwapi_resource_dll.c new file mode 100644 index 00000000000..2b8ad67d993 --- /dev/null +++ b/modules/rostests/apitests/shlwapi/shlwapi_resource_dll/shlwapi_resource_dll.c @@ -0,0 +1,27 @@ +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include <windows.h> + +BOOL WINAPI +DllMain(IN HINSTANCE hDllHandle, + IN DWORD dwReason, + IN LPVOID lpvReserved) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + HANDLE hEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, "Local\shlwapi_apitest_evt"); + if (hEvent != NULL) + { + SetEvent(hEvent); + CloseHandle(hEvent); + } + else + { + OutputDebugStringA("ERROR: NO EVENT FOUND!\n"); + } + } + + return TRUE; +} diff --git a/modules/rostests/apitests/shlwapi/shlwapi_resource_dll/shlwapi_resource_dll.rc b/modules/rostests/apitests/shlwapi/shlwapi_resource_dll/shlwapi_resource_dll.rc new file mode 100644 index 00000000000..ff9d09e6181 --- /dev/null +++ b/modules/rostests/apitests/shlwapi/shlwapi_resource_dll/shlwapi_resource_dll.rc @@ -0,0 +1,9 @@ +#include <windef.h> + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +STRINGTABLE +BEGIN + 3 "Test string one." +END + diff --git a/modules/rostests/apitests/shlwapi/testdata.rc b/modules/rostests/apitests/shlwapi/testdata.rc index b6aa19173ef..c57a6dabc6f 100644 --- a/modules/rostests/apitests/shlwapi/testdata.rc +++ b/modules/rostests/apitests/shlwapi/testdata.rc @@ -8,3 +8,6 @@ ICON_16_32_RED ICON "16_32_red.ico" ICON_32_8 ICON "32_8.ico" ICON_32_32 ICON "32_32.ico"
+ +101 10 "shlwapi_resource_dll.dll" + diff --git a/modules/rostests/apitests/shlwapi/testlist.c b/modules/rostests/apitests/shlwapi/testlist.c index 1ad20a3bf8a..6bf3fe27892 100644 --- a/modules/rostests/apitests/shlwapi/testlist.c +++ b/modules/rostests/apitests/shlwapi/testlist.c @@ -8,6 +8,7 @@ extern void func_isuncpathservershare(void); extern void func_PathUnExpandEnvStrings(void); extern void func_PathUnExpandEnvStringsForUser(void); extern void func_SHAreIconsEqual(void); +extern void func_SHLoadIndirectString(void); extern void func_StrFormatByteSizeW(void);
const struct test winetest_testlist[] = @@ -19,6 +20,7 @@ const struct test winetest_testlist[] = { "PathUnExpandEnvStrings", func_PathUnExpandEnvStrings }, { "PathUnExpandEnvStringsForUser", func_PathUnExpandEnvStringsForUser }, { "SHAreIconsEqual", func_SHAreIconsEqual }, + { "SHLoadIndirectString", func_SHLoadIndirectString }, { "StrFormatByteSizeW", func_StrFormatByteSizeW }, { 0, 0 } };