1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Test for LoadImageW using DLL compiled with MSVC 5 * COPYRIGHT: Copyright 2024 Doug Lyons <douglyons@douglyons.com> 6 * 7 * NOTES: 8 * Works on ReactOS, but not on Windows 2003 Server SP2. 9 */ 10 11 #include "precomp.h" 12 #include "resource.h" 13 #include <stdio.h> 14 #include <versionhelpers.h> 15 16 BOOL FileExistsW(PCWSTR FileName) 17 { 18 DWORD Attribute = GetFileAttributesW(FileName); 19 20 return (Attribute != INVALID_FILE_ATTRIBUTES && 21 !(Attribute & FILE_ATTRIBUTE_DIRECTORY)); 22 } 23 24 BOOL ResourceToFileW(INT i, PCWSTR FileName) 25 { 26 FILE *fout; 27 HGLOBAL hData; 28 HRSRC hRes; 29 PVOID pResLock; 30 UINT iSize; 31 32 if (FileExistsW(FileName)) 33 { 34 /* We should only be using %temp% paths, so deleting here should be OK */ 35 printf("Deleting '%S' that already exists.\n", FileName); 36 DeleteFileW(FileName); 37 } 38 39 hRes = FindResourceW(NULL, MAKEINTRESOURCEW(i), MAKEINTRESOURCEW(RT_RCDATA)); 40 if (hRes == NULL) 41 { 42 skip("Could not locate resource (%d). Exiting now\n", i); 43 return FALSE; 44 } 45 46 iSize = SizeofResource(NULL, hRes); 47 48 hData = LoadResource(NULL, hRes); 49 if (hData == NULL) 50 { 51 skip("Could not load resource (%d). Exiting now\n", i); 52 return FALSE; 53 } 54 55 // Lock the resource into global memory. 56 pResLock = LockResource(hData); 57 if (pResLock == NULL) 58 { 59 skip("Could not lock resource (%d). Exiting now\n", i); 60 return FALSE; 61 } 62 63 fout = _wfopen(FileName, L"wb"); 64 fwrite(pResLock, iSize, 1, fout); 65 fclose(fout); 66 return TRUE; 67 } 68 69 static struct 70 { 71 PCWSTR FileName; 72 INT ResourceId; 73 } DataFiles[] = 74 { 75 {L"%SystemRoot%\\bin\\image.dll", IDR_DLL_NORMAL}, 76 }; 77 78 79 START_TEST(LoadImageGCC) 80 { 81 UINT i; 82 WCHAR PathBuffer[MAX_PATH]; 83 static HBITMAP hBmp; 84 HANDLE handle; 85 HDC hdcMem; 86 BITMAP bitmap; 87 BITMAPINFO bmi; 88 HGLOBAL hMem; 89 LPVOID lpBits; 90 CHAR img[8] = { 0 }; 91 UINT size; 92 93 /* Windows 2003 cannot run this test. Testman shows CRASH, so skip it. */ 94 if (!IsReactOS()) 95 return; 96 97 /* Extract Data Files */ 98 for (i = 0; i < _countof(DataFiles); ++i) 99 { 100 ExpandEnvironmentStringsW(DataFiles[i].FileName, PathBuffer, _countof(PathBuffer)); 101 102 if (!ResourceToFileW(DataFiles[i].ResourceId, PathBuffer)) 103 { 104 printf("ResourceToFile Failed. Exiting now\n"); 105 goto Cleanup; 106 } 107 } 108 109 handle = LoadLibraryExW(PathBuffer, NULL, LOAD_LIBRARY_AS_DATAFILE); 110 hBmp = (HBITMAP)LoadImage(handle, MAKEINTRESOURCE(130), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 111 112 hdcMem = CreateCompatibleDC(NULL); 113 SelectObject(hdcMem, hBmp); 114 GetObject(hBmp, sizeof(BITMAP), &bitmap); 115 116 memset(&bmi, 0, sizeof(bmi)); 117 memset(&bmi, 0, sizeof(bmi)); 118 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 119 bmi.bmiHeader.biWidth = bitmap.bmWidth; 120 bmi.bmiHeader.biHeight = bitmap.bmHeight; 121 bmi.bmiHeader.biPlanes = bitmap.bmPlanes; 122 bmi.bmiHeader.biBitCount = bitmap.bmBitsPixel; 123 bmi.bmiHeader.biCompression = BI_RGB; 124 bmi.bmiHeader.biSizeImage = 0; 125 126 size = ((bitmap.bmWidth * bmi.bmiHeader.biBitCount + 31) / 32) * 4 * bitmap.bmHeight; 127 128 hMem = GlobalAlloc(GMEM_MOVEABLE, size); 129 lpBits = GlobalLock(hMem); 130 GetDIBits(hdcMem, hBmp, 0, bitmap.bmHeight, lpBits, &bmi, DIB_RGB_COLORS); 131 132 /* Get first 8 bytes of second row of bits from bitmap */ 133 memcpy(img, (VOID *)((INT_PTR)lpBits + 4 * bitmap.bmWidth), 8); 134 135 ok(img[0] == 0, "Byte 0 Bad. Got 0x%02x, expected 0\n", img[0] & 0xff); 136 ok(img[1] == 0, "Byte 1 Bad. Got 0x%02x, expected 0\n", img[1] & 0xff); 137 ok(img[2] == 0, "Byte 2 Bad. Got 0x%02x, expected 0\n", img[2] & 0xff); 138 ok(img[3] == 0, "Byte 3 Bad. Got 0x%02x, expected 0\n", img[3] & 0xff); 139 140 GlobalUnlock(hMem); 141 GlobalFree(hMem); 142 143 DeleteDC(hdcMem); 144 145 Cleanup: 146 for (i = 0; i < _countof(DataFiles); ++i) 147 { 148 ExpandEnvironmentStringsW(DataFiles[i].FileName, PathBuffer, _countof(PathBuffer)); 149 DeleteFileW(PathBuffer); 150 } 151 } 152