1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Tests for SHLoadIndirectString 5 * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include <apitest.h> 9 #include <shlwapi.h> 10 #include "resource.h" 11 12 #include <pseh/pseh2.h> 13 14 static void execute_test(LPCWSTR DllFile) 15 { 16 WCHAR DllBuffer[MAX_PATH + 20]; 17 WCHAR Buffer[MAX_PATH * 2] = {0}; 18 HRESULT hr; 19 HANDLE hEvent; 20 DWORD dwRet; 21 HMODULE mod; 22 23 hEvent = CreateEventA(NULL, TRUE, FALSE, "Local\\shlwapi_apitest_evt"); 24 25 // Show that it is not signaled 26 dwRet = WaitForSingleObject(hEvent, 1); 27 ok_hex(dwRet, WAIT_TIMEOUT); 28 29 // Ensure the module is not loaded yet... 30 mod = GetModuleHandleW(DllFile); 31 if (mod != NULL) 32 { 33 CloseHandle(hEvent); 34 skip("%S loaded, cannot continue\n", DllFile); 35 return; 36 } 37 38 wsprintfW(DllBuffer, L"@%s,-3", DllFile); 39 40 // Load a string from the dll 41 hr = SHLoadIndirectString(DllBuffer, Buffer, _countof(Buffer), NULL); 42 ok_hex(hr, S_OK); 43 if (SUCCEEDED(hr)) 44 { 45 // Module should still not be loaded 46 mod = GetModuleHandleW(DllFile); 47 ok_ptr(mod, 0); 48 49 ok_wstr(Buffer, L"Test string one."); 50 51 // DllMain not called.. 52 dwRet = WaitForSingleObject(hEvent, 1); 53 ok_hex(dwRet, WAIT_TIMEOUT); 54 55 // Show that calling DllMain will set the event 56 mod = LoadLibraryW(DllFile); 57 ok(mod != NULL, "Failed to load %S\n", DllFile); 58 59 if (mod) 60 { 61 dwRet = WaitForSingleObject(hEvent, 1); 62 ok_hex(dwRet, WAIT_OBJECT_0); 63 FreeLibrary(mod); 64 } 65 } 66 CloseHandle(hEvent); 67 } 68 69 70 BOOL extract_resource(const WCHAR* Filename, LPCWSTR ResourceName) 71 { 72 BOOL Success; 73 DWORD dwWritten, Size; 74 HGLOBAL hGlobal; 75 LPVOID pData; 76 HANDLE Handle; 77 HRSRC hRsrc = FindResourceW(GetModuleHandleW(NULL), ResourceName, (LPCWSTR)10); 78 ok(!!hRsrc, "Unable to find %s\n", wine_dbgstr_w(ResourceName)); 79 if (!hRsrc) 80 return FALSE; 81 82 hGlobal = LoadResource(GetModuleHandleW(NULL), hRsrc); 83 Size = SizeofResource(GetModuleHandleW(NULL), hRsrc); 84 pData = LockResource(hGlobal); 85 86 ok(Size && !!pData, "Unable to load %s\n", wine_dbgstr_w(ResourceName)); 87 if (!Size || !pData) 88 return FALSE; 89 90 Handle = CreateFileW(Filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 91 92 if (Handle == INVALID_HANDLE_VALUE) 93 { 94 skip("Failed to create temp file %ls, error %lu\n", Filename, GetLastError()); 95 return FALSE; 96 } 97 Success = WriteFile(Handle, pData, Size, &dwWritten, NULL); 98 ok(Success == TRUE, "WriteFile failed with %lu\n", GetLastError()); 99 ok(dwWritten == Size, "WriteFile wrote %lu bytes instead of %lu\n", dwWritten, Size); 100 CloseHandle(Handle); 101 Success = Success && (dwWritten == Size); 102 103 UnlockResource(pData); 104 return Success; 105 } 106 107 START_TEST(SHLoadIndirectString) 108 { 109 WCHAR workdir[MAX_PATH], dllpath[MAX_PATH]; 110 BOOL ret; 111 UINT Length; 112 113 ret = GetTempPathW(_countof(workdir), workdir); 114 ok(ret, "GetTempPathW error: %lu\n", GetLastError()); 115 116 Length = GetTempFileNameW(workdir, L"ntdll", 0, dllpath); 117 ok(Length != 0, "GetTempFileNameW failed with %lu\n", GetLastError()); 118 119 if (extract_resource(dllpath, (LPCWSTR)101)) 120 { 121 _SEH2_TRY 122 { 123 execute_test(dllpath); 124 } 125 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 126 { 127 ok(0, "Ldr didnt handle exception\n"); 128 } 129 _SEH2_END; 130 } 131 else 132 { 133 ok(0, "Failed to extract resource\n"); 134 } 135 136 DeleteFileW(dllpath); 137 } 138