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
FileExistsW(PCWSTR FileName)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
ResourceToFileW(INT i,PCWSTR FileName)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
START_TEST(LoadImageGCC)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