[SHLWAPI_APITEST] Add test showing SHLoadIndirectString should load a dll as datafile

This commit is contained in:
Mark Jansen 2020-05-18 21:38:56 +02:00
parent 07f98eb10a
commit 922a956805
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
7 changed files with 190 additions and 0 deletions

View file

@ -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)

View file

@ -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);
}

View file

@ -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)

View file

@ -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;
}

View file

@ -0,0 +1,9 @@
#include <windef.h>
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
STRINGTABLE
BEGIN
3 "Test string one."
END

View file

@ -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"

View file

@ -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 }
};