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