https://git.reactos.org/?p=reactos.git;a=commitdiff;h=922a956805ab41f26583f…
commit 922a956805ab41f26583fbd6cc2c7120a01008e1
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Mon May 18 21:38:56 2020 +0200
Commit: Mark Jansen <mark.jansen(a)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(a)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 }
};