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